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