move revealed-count mechanism to fports.c
[bpt/guile.git] / libguile / ports.h
1 /* classes: h_files */
2
3 #ifndef SCM_PORTS_H
4 #define SCM_PORTS_H
5
6 /* Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004,
7 * 2006, 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 3 of
12 * the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 * 02110-1301 USA
23 */
24
25 \f
26
27 #include "libguile/__scm.h"
28
29 #include <stdio.h>
30 #include <string.h>
31 #include <unistd.h>
32 #include "libguile/gc.h"
33 #include "libguile/tags.h"
34 #include "libguile/error.h"
35 #include "libguile/print.h"
36 #include "libguile/struct.h"
37 #include "libguile/threads.h"
38 #include "libguile/strings.h"
39
40 \f
41
42 #define SCM_INITIAL_PUTBACK_BUF_SIZE 4
43
44 /* values for the rw_active flag. */
45 typedef enum scm_t_port_rw_active {
46 SCM_PORT_NEITHER = 0,
47 SCM_PORT_READ = 1,
48 SCM_PORT_WRITE = 2
49 } scm_t_port_rw_active;
50
51 typedef enum scm_t_port_encoding_mode {
52 SCM_PORT_ENCODING_MODE_UTF8,
53 SCM_PORT_ENCODING_MODE_ICONV
54 } scm_t_port_encoding_mode;
55
56 /* This is a separate object so that only those ports that use iconv
57 cause finalizers to be registered. */
58 typedef struct scm_t_iconv_descriptors
59 {
60 /* input/output iconv conversion descriptors */
61 void *input_cd;
62 void *output_cd;
63 } scm_t_iconv_descriptors;
64
65 /* C representation of a Scheme port. */
66
67 typedef struct
68 {
69 SCM port; /* Link back to the port object. */
70 scm_i_pthread_mutex_t *lock; /* A recursive lock for this port. */
71
72 /* data for the underlying port implementation as a raw C value. */
73 scm_t_bits stream;
74
75 SCM file_name; /* debugging support. */
76 long line_number; /* debugging support. */
77 int column_number; /* debugging support. */
78
79 /* port buffers. the buffer(s) are set up for all ports.
80 in the case of string ports, the buffer is the string itself.
81 in the case of unbuffered file ports, the buffer is a
82 single char: shortbuf. */
83
84 /* this buffer is filled from read_buf to read_end using the ptob
85 buffer_fill. then input requests are taken from read_pos until
86 it reaches read_end. */
87
88 unsigned char *read_buf; /* buffer start. */
89 const unsigned char *read_pos;/* the next unread char. */
90 unsigned char *read_end; /* pointer to last buffered char + 1. */
91 scm_t_off read_buf_size; /* size of the buffer. */
92
93 /* when chars are put back into the buffer, e.g., using peek-char or
94 unread-string, the read-buffer pointers are switched to cbuf.
95 the original pointers are saved here and restored when the put-back
96 chars have been consumed. */
97 unsigned char *saved_read_buf;
98 const unsigned char *saved_read_pos;
99 unsigned char *saved_read_end;
100 scm_t_off saved_read_buf_size;
101
102 /* write requests are saved into this buffer at write_pos until it
103 reaches write_buf + write_buf_size, then the ptob flush is
104 called. */
105
106 unsigned char *write_buf; /* buffer start. */
107 unsigned char *write_pos; /* pointer to last buffered char + 1. */
108 unsigned char *write_end; /* pointer to end of buffer + 1. */
109 scm_t_off write_buf_size; /* size of the buffer. */
110
111 unsigned char shortbuf; /* buffer for "unbuffered" streams. */
112
113 int rw_random; /* true if the port is random access.
114 implies that the buffers must be
115 flushed before switching between
116 reading and writing, seeking, etc. */
117
118 scm_t_port_rw_active rw_active; /* for random access ports,
119 indicates which of the buffers
120 is currently in use. can be
121 SCM_PORT_WRITE, SCM_PORT_READ,
122 or SCM_PORT_NEITHER. */
123
124
125 /* a buffer for un-read chars and strings. */
126 unsigned char *putback_buf;
127 size_t putback_buf_size; /* allocated size of putback_buf. */
128
129 /* Character encoding support */
130 char *encoding;
131 scm_t_port_encoding_mode encoding_mode;
132 scm_t_string_failed_conversion_handler ilseq_handler;
133 scm_t_iconv_descriptors *iconv_descriptors;
134 } scm_t_port;
135
136
137 SCM_INTERNAL SCM scm_i_port_weak_set;
138
139
140 #define SCM_READ_BUFFER_EMPTY_P(c_port) (c_port->read_pos >= c_port->read_end)
141
142 \f
143
144 #define SCM_EOF_OBJECT_P(x) (scm_is_eq ((x), SCM_EOF_VAL))
145
146 /* PORT FLAGS
147 * A set of flags characterizes a port.
148 * Note that we reserve the bits 1 << 24 and above for use by the
149 * routines in the port's scm_ptobfuns structure.
150 */
151 #define SCM_OPN (1L<<16) /* Is the port open? */
152 #define SCM_RDNG (2L<<16) /* Is it a readable port? */
153 #define SCM_WRTNG (4L<<16) /* Is it writable? */
154 #define SCM_BUF0 (8L<<16) /* Is it unbuffered? */
155 #define SCM_BUFLINE (64L<<16) /* Is it line-buffered? */
156
157 #define SCM_PORTP(x) (SCM_HAS_TYP7 (x, scm_tc7_port))
158 #define SCM_OPPORTP(x) (SCM_PORTP (x) && (SCM_CELL_WORD_0 (x) & SCM_OPN))
159 #define SCM_INPUT_PORT_P(x) (SCM_PORTP (x) && (SCM_CELL_WORD_0 (x) & SCM_RDNG))
160 #define SCM_OUTPUT_PORT_P(x) (SCM_PORTP (x) && (SCM_CELL_WORD_0 (x) & SCM_WRTNG))
161 #define SCM_OPINPORTP(x) (SCM_OPPORTP (x) && SCM_INPUT_PORT_P (x))
162 #define SCM_OPOUTPORTP(x) (SCM_OPPORTP (x) && SCM_OUTPUT_PORT_P (x))
163 #define SCM_OPENP(x) (SCM_OPPORTP (x))
164 #define SCM_CLOSEDP(x) (!SCM_OPENP (x))
165 #define SCM_CLR_PORT_OPEN_FLAG(p) \
166 SCM_SET_CELL_WORD_0 ((p), SCM_CELL_WORD_0 (p) & ~SCM_OPN)
167
168 #define SCM_PTAB_ENTRY(x) ((scm_t_port *) SCM_CELL_WORD_1 (x))
169 #define SCM_PORT_DESCRIPTOR(port) ((scm_t_ptob_descriptor *) SCM_CELL_WORD_2 (port))
170 #define SCM_SETPTAB_ENTRY(x, ent) (SCM_SET_CELL_WORD_1 ((x), (scm_t_bits) (ent)))
171 #define SCM_STREAM(x) (SCM_PTAB_ENTRY(x)->stream)
172 #define SCM_SETSTREAM(x, s) (SCM_PTAB_ENTRY(x)->stream = (scm_t_bits) (s))
173 #define SCM_FILENAME(x) (SCM_PTAB_ENTRY(x)->file_name)
174 #define SCM_SET_FILENAME(x, n) (SCM_PTAB_ENTRY(x)->file_name = (n))
175 #define SCM_LINUM(x) (SCM_PTAB_ENTRY(x)->line_number)
176 #define SCM_COL(x) (SCM_PTAB_ENTRY(x)->column_number)
177
178 #define SCM_INCLINE(port) do {SCM_LINUM (port) += 1; SCM_COL (port) = 0;} while (0)
179 #define SCM_ZEROCOL(port) do {SCM_COL (port) = 0;} while (0)
180 #define SCM_INCCOL(port) do {SCM_COL (port) += 1;} while (0)
181 #define SCM_DECCOL(port) do {if (SCM_COL (port) > 0) SCM_COL (port) -= 1;} while (0)
182 #define SCM_TABCOL(port) do {SCM_COL (port) += 8 - SCM_COL (port) % 8;} while (0)
183
184 /* Maximum number of port types. */
185 #define SCM_I_MAX_PORT_TYPE_COUNT 256
186
187 \f
188
189 typedef enum scm_t_port_type_flags {
190 SCM_PORT_TYPE_HAS_FLUSH = 1 << 0
191 } scm_t_port_type_flags;
192
193 /* port-type description. */
194 typedef struct scm_t_ptob_descriptor
195 {
196 char *name;
197 SCM (*mark) (SCM);
198 size_t (*free) (SCM);
199 int (*print) (SCM exp, SCM port, scm_print_state *pstate);
200 SCM (*equalp) (SCM, SCM);
201 int (*close) (SCM port);
202
203 void (*write) (SCM port, const void *data, size_t size);
204 void (*flush) (SCM port);
205
206 void (*end_input) (SCM port, int offset);
207 int (*fill_input) (SCM port);
208 int (*input_waiting) (SCM port);
209
210 scm_t_off (*seek) (SCM port, scm_t_off OFFSET, int WHENCE);
211 void (*truncate) (SCM port, scm_t_off length);
212
213 unsigned flags;
214 } scm_t_ptob_descriptor;
215
216 #define SCM_TC2PTOBNUM(x) (0x0ff & ((x) >> 8))
217 #define SCM_PTOBNUM(x) (SCM_TC2PTOBNUM (SCM_CELL_TYPE (x)))
218 /* SCM_PTOBNAME can be 0 if name is missing */
219 #define SCM_PTOBNAME(ptobnum) (scm_c_port_type_ref (ptobnum)->name)
220
221 /* Port types, and their vtables. */
222 SCM_INTERNAL long scm_c_num_port_types (void);
223 SCM_API scm_t_ptob_descriptor* scm_c_port_type_ref (long ptobnum);
224 SCM_API long scm_c_port_type_add_x (scm_t_ptob_descriptor *desc);
225 SCM_API scm_t_bits scm_make_port_type (char *name,
226 int (*fill_input) (SCM port),
227 void (*write) (SCM port,
228 const void *data,
229 size_t size));
230 SCM_API void scm_set_port_mark (scm_t_bits tc, SCM (*mark) (SCM));
231 SCM_API void scm_set_port_free (scm_t_bits tc, size_t (*free) (SCM));
232 SCM_API void scm_set_port_print (scm_t_bits tc,
233 int (*print) (SCM exp,
234 SCM port,
235 scm_print_state *pstate));
236 SCM_API void scm_set_port_equalp (scm_t_bits tc, SCM (*equalp) (SCM, SCM));
237 SCM_API void scm_set_port_close (scm_t_bits tc, int (*close) (SCM));
238
239 SCM_API void scm_set_port_flush (scm_t_bits tc, void (*flush) (SCM port));
240 SCM_API void scm_set_port_end_input (scm_t_bits tc,
241 void (*end_input) (SCM port,
242 int offset));
243 SCM_API void scm_set_port_seek (scm_t_bits tc,
244 scm_t_off (*seek) (SCM port,
245 scm_t_off OFFSET,
246 int WHENCE));
247 SCM_API void scm_set_port_truncate (scm_t_bits tc,
248 void (*truncate) (SCM port,
249 scm_t_off length));
250 SCM_API void scm_set_port_input_waiting (scm_t_bits tc, int (*input_waiting) (SCM));
251
252 /* The input, output, error, and load ports. */
253 SCM_API SCM scm_current_input_port (void);
254 SCM_API SCM scm_current_output_port (void);
255 SCM_API SCM scm_current_error_port (void);
256 SCM_API SCM scm_current_warning_port (void);
257 SCM_API SCM scm_current_load_port (void);
258 SCM_API SCM scm_set_current_input_port (SCM port);
259 SCM_API SCM scm_set_current_output_port (SCM port);
260 SCM_API SCM scm_set_current_error_port (SCM port);
261 SCM_API SCM scm_set_current_warning_port (SCM port);
262 SCM_API void scm_dynwind_current_input_port (SCM port);
263 SCM_API void scm_dynwind_current_output_port (SCM port);
264 SCM_API void scm_dynwind_current_error_port (SCM port);
265 SCM_INTERNAL void scm_i_dynwind_current_load_port (SCM port);
266
267 /* Mode bits. */
268 SCM_INTERNAL long scm_i_mode_bits (SCM modes);
269 SCM_API long scm_mode_bits (char *modes);
270 SCM_API SCM scm_port_mode (SCM port);
271
272 /* Low-level constructors. */
273 SCM_API SCM
274 scm_c_make_port_with_encoding (scm_t_bits tag,
275 unsigned long mode_bits,
276 const char *encoding,
277 scm_t_string_failed_conversion_handler handler,
278 scm_t_bits stream);
279 SCM_API SCM scm_c_make_port (scm_t_bits tag, unsigned long mode_bits,
280 scm_t_bits stream);
281 SCM_API SCM scm_new_port_table_entry (scm_t_bits tag);
282
283 /* Predicates. */
284 SCM_API SCM scm_port_p (SCM x);
285 SCM_API SCM scm_input_port_p (SCM x);
286 SCM_API SCM scm_output_port_p (SCM x);
287 SCM_API SCM scm_port_closed_p (SCM port);
288 SCM_API SCM scm_eof_object_p (SCM x);
289
290 /* Closing ports. */
291 SCM_API SCM scm_close_port (SCM port);
292 SCM_API SCM scm_close_input_port (SCM port);
293 SCM_API SCM scm_close_output_port (SCM port);
294
295 /* Encoding characters to byte streams, and decoding byte streams to
296 characters. */
297 SCM_INTERNAL const char *scm_i_default_port_encoding (void);
298 SCM_INTERNAL void scm_i_set_default_port_encoding (const char *);
299 SCM_INTERNAL scm_t_iconv_descriptors *scm_i_port_iconv_descriptors (SCM port);
300 SCM_INTERNAL void scm_i_set_port_encoding_x (SCM port, const char *str);
301 SCM_API SCM scm_port_encoding (SCM port);
302 SCM_API SCM scm_set_port_encoding_x (SCM port, SCM encoding);
303 SCM_INTERNAL scm_t_string_failed_conversion_handler scm_i_get_conversion_strategy (SCM port);
304 SCM_INTERNAL void scm_i_set_conversion_strategy_x (SCM port,
305 scm_t_string_failed_conversion_handler h);
306 SCM_API SCM scm_port_conversion_strategy (SCM port);
307 SCM_API SCM scm_set_port_conversion_strategy_x (SCM port, SCM behavior);
308
309 /* Acquiring and releasing the port lock. */
310 SCM_API void scm_dynwind_lock_port (SCM port);
311 SCM_INLINE int scm_c_lock_port (SCM port, scm_i_pthread_mutex_t **lock);
312 SCM_INLINE int scm_c_try_lock_port (SCM port, scm_i_pthread_mutex_t **lock);
313
314 /* Input. */
315 SCM_API int scm_get_byte_or_eof (SCM port);
316 SCM_INLINE int scm_get_byte_or_eof_unlocked (SCM port);
317 SCM_API int scm_peek_byte_or_eof (SCM port);
318 SCM_INLINE int scm_peek_byte_or_eof_unlocked (SCM port);
319 SCM_API size_t scm_c_read (SCM port, void *buffer, size_t size);
320 SCM_API size_t scm_c_read_unlocked (SCM port, void *buffer, size_t size);
321 SCM_API scm_t_wchar scm_getc (SCM port);
322 SCM_API scm_t_wchar scm_getc_unlocked (SCM port);
323 SCM_API SCM scm_read_char (SCM port);
324
325 /* Pushback. */
326 SCM_INTERNAL void scm_unget_byte (int c, SCM port);
327 SCM_INTERNAL void scm_unget_byte_unlocked (int c, SCM port);
328 SCM_API void scm_ungetc (scm_t_wchar c, SCM port);
329 SCM_API void scm_ungetc_unlocked (scm_t_wchar c, SCM port);
330 SCM_API void scm_ungets (const char *s, int n, SCM port);
331 SCM_API void scm_ungets_unlocked (const char *s, int n, SCM port);
332 SCM_API SCM scm_peek_char (SCM port);
333 SCM_API SCM scm_unread_char (SCM cobj, SCM port);
334 SCM_API SCM scm_unread_string (SCM str, SCM port);
335
336 /* Manipulating the buffers. */
337 SCM_API void scm_port_non_buffer (scm_t_port *pt);
338 SCM_API int scm_fill_input (SCM port);
339 SCM_API int scm_fill_input_unlocked (SCM port);
340 SCM_INTERNAL size_t scm_take_from_input_buffers (SCM port, char *dest, size_t read_len);
341 SCM_API SCM scm_drain_input (SCM port);
342 SCM_API void scm_end_input (SCM port);
343 SCM_API void scm_end_input_unlocked (SCM port);
344 SCM_API SCM scm_force_output (SCM port);
345 SCM_API void scm_flush (SCM port);
346 SCM_API void scm_flush_unlocked (SCM port);
347
348 /* Output. */
349 SCM_API void scm_putc (char c, SCM port);
350 SCM_INLINE void scm_putc_unlocked (char c, SCM port);
351 SCM_API void scm_puts (const char *str_data, SCM port);
352 SCM_INLINE void scm_puts_unlocked (const char *str_data, SCM port);
353 SCM_API void scm_c_write (SCM port, const void *buffer, size_t size);
354 SCM_API void scm_c_write_unlocked (SCM port, const void *buffer, size_t size);
355 SCM_API void scm_lfwrite (const char *ptr, size_t size, SCM port);
356 SCM_API void scm_lfwrite_unlocked (const char *ptr, size_t size, SCM port);
357 SCM_INTERNAL void scm_lfwrite_substr (SCM str, size_t start, size_t end,
358 SCM port);
359
360 /* Querying and setting positions, and character availability. */
361 SCM_API SCM scm_char_ready_p (SCM port);
362 SCM_API SCM scm_seek (SCM object, SCM offset, SCM whence);
363 SCM_API SCM scm_truncate_file (SCM object, SCM length);
364 SCM_API SCM scm_port_line (SCM port);
365 SCM_API SCM scm_set_port_line_x (SCM port, SCM line);
366 SCM_API SCM scm_port_column (SCM port);
367 SCM_API SCM scm_set_port_column_x (SCM port, SCM line);
368 SCM_API SCM scm_port_filename (SCM port);
369 SCM_API SCM scm_set_port_filename_x (SCM port, SCM filename);
370
371 /* Implementation helpers for port printing functions. */
372 SCM_API int scm_port_print (SCM exp, SCM port, scm_print_state *);
373 SCM_API void scm_print_port_mode (SCM exp, SCM port);
374
375 /* Iterating over all ports. */
376 SCM_API SCM scm_port_for_each (SCM proc);
377 SCM_API void scm_c_port_for_each (void (*proc)(void *data, SCM p), void *data);
378 SCM_API SCM scm_flush_all_ports (void);
379
380 /* Void ports. */
381 SCM_API SCM scm_void_port (char * mode_str);
382 SCM_API SCM scm_sys_make_void_port (SCM mode);
383
384 /* Initialization. */
385 SCM_INTERNAL void scm_init_ports (void);
386
387
388 /* Inline function implementations. */
389
390 #if SCM_CAN_INLINE || defined SCM_INLINE_C_IMPLEMENTING_INLINES
391 SCM_INLINE_IMPLEMENTATION int
392 scm_c_lock_port (SCM port, scm_i_pthread_mutex_t **lock)
393 {
394 *lock = SCM_PTAB_ENTRY (port)->lock;
395
396 if (*lock)
397 return scm_i_pthread_mutex_lock (*lock);
398 else
399 return 0;
400 }
401
402 SCM_INLINE_IMPLEMENTATION int
403 scm_c_try_lock_port (SCM port, scm_i_pthread_mutex_t **lock)
404 {
405 *lock = SCM_PTAB_ENTRY (port)->lock;
406 if (*lock)
407 {
408 int ret = scm_i_pthread_mutex_trylock (*lock);
409 if (ret != 0)
410 *lock = NULL;
411 return ret;
412 }
413 else
414 return 0;
415 }
416
417 SCM_INLINE_IMPLEMENTATION int
418 scm_get_byte_or_eof_unlocked (SCM port)
419 {
420 int c;
421 scm_t_port *pt = SCM_PTAB_ENTRY (port);
422
423 if (pt->rw_active == SCM_PORT_WRITE)
424 /* may be marginally faster than calling scm_flush. */
425 SCM_PORT_DESCRIPTOR (port)->flush (port);
426
427 if (pt->rw_random)
428 pt->rw_active = SCM_PORT_READ;
429
430 if (pt->read_pos >= pt->read_end)
431 {
432 if (SCM_UNLIKELY (scm_fill_input_unlocked (port) == EOF))
433 return EOF;
434 }
435
436 c = *(pt->read_pos++);
437
438 return c;
439 }
440
441 /* Like `scm_get_byte_or_eof' but does not change PORT's `read_pos'. */
442 SCM_INLINE_IMPLEMENTATION int
443 scm_peek_byte_or_eof_unlocked (SCM port)
444 {
445 int c;
446 scm_t_port *pt = SCM_PTAB_ENTRY (port);
447
448 if (pt->rw_active == SCM_PORT_WRITE)
449 /* may be marginally faster than calling scm_flush. */
450 SCM_PORT_DESCRIPTOR (port)->flush (port);
451
452 if (pt->rw_random)
453 pt->rw_active = SCM_PORT_READ;
454
455 if (pt->read_pos >= pt->read_end)
456 {
457 if (SCM_UNLIKELY (scm_fill_input_unlocked (port) == EOF))
458 return EOF;
459 }
460
461 c = *pt->read_pos;
462
463 return c;
464 }
465
466 SCM_INLINE_IMPLEMENTATION void
467 scm_putc_unlocked (char c, SCM port)
468 {
469 SCM_ASSERT_TYPE (SCM_OPOUTPORTP (port), port, 0, NULL, "output port");
470 scm_lfwrite_unlocked (&c, 1, port);
471 }
472
473 SCM_INLINE_IMPLEMENTATION void
474 scm_puts_unlocked (const char *s, SCM port)
475 {
476 SCM_ASSERT_TYPE (SCM_OPOUTPORTP (port), port, 0, NULL, "output port");
477 scm_lfwrite_unlocked (s, strlen (s), port);
478 }
479 #endif /* SCM_CAN_INLINE || defined SCM_INLINE_C_IMPLEMENTING_INLINES */
480
481 #endif /* SCM_PORTS_H */
482
483 /*
484 Local Variables:
485 c-file-style: "gnu"
486 End:
487 */