1 /*
2  * gauche/port.h - Port API
3  *
4  *   Copyright (c) 2000-2020  Shiro Kawai  <shiro@acm.org>
5  *
6  *   Redistribution and use in source and binary forms, with or without
7  *   modification, are permitted provided that the following conditions
8  *   are met:
9  *
10  *   1. Redistributions of source code must retain the above copyright
11  *      notice, this list of conditions and the following disclaimer.
12  *
13  *   2. Redistributions in binary form must reproduce the above copyright
14  *      notice, this list of conditions and the following disclaimer in the
15  *      documentation and/or other materials provided with the distribution.
16  *
17  *   3. Neither the name of the authors nor the names of its contributors
18  *      may be used to endorse or promote products derived from this
19  *      software without specific prior written permission.
20  *
21  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27  *   TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28  *   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29  *   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30  *   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31  *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 #ifndef GAUCHE_PORT_H
35 #define GAUCHE_PORT_H
36 
37 /* Port is the Scheme way of I/O abstraction.  R5RS's definition of
38  * of the port is very simple and straightforward.   Practical
39  * applications, however, require far more detailed control over
40  * the I/O channel, as well as the reasonable performance.
41  *
42  * Current implementation is a bit messy, trying to achieve both
43  * performance and feature requirements.  In the core API level,
44  * ports are categorized in one of three types: file ports, string
45  * ports and procedural ports.   A port may be an input port or
46  * an output port.   A port may handle byte (binary) streams,
47  * as well as character streams.  Some port may
48  * interchange byte (binary) I/O versus character I/O, while some
49  * may signal an error if you mix those operations.
50  *
51  * You shouldn't rely on the underlying port implementation, for
52  * it is likely to be changed in future.  There are enough macros
53  * and API functions provided to use and extend the port mechanism.
54  * See also ext/vport for the way to extend the port from Scheme.
55  *
56  * Most public port APIs locks the given port to ensure it won't
57  * interfere with other threads.  Some basic APIs have corresponding
58  * "Unsafe" version (e.g. Scm_Putc() vs Scm_PutcUnsafe()), which
59  * assumes the caller already has the lock; but the base version
60  * won't do extra locking when the calling thread alreay hold the lock,
61  * so there's no reason for general code to call unsafe verson directly.
62  */
63 
64 /*================================================================
65  * Port structures & flags
66  */
67 
68 /* Substructures */
69 
70 /* The alternative of FILE* structure, used by buffered (file) port.
71    The members are owned by the port, and client shouldn't change the
72    elements.  You can create your own custom buffered port by using
73    Scm_MakeBufferedPort() --- with it, you pass ScmPortBuffer with
74    the function pointers filled in, which is copied to the port's
75    internal ScmPortBuffer structure.
76    See port.c for the details of function pointers. */
77 
78 typedef struct ScmPortBufferRec {
79     char *buffer;       /* ptr to the buffer area */
80     char *current;      /* current buffer position */
81     char *end;          /* the end of the current valid data */
82     ScmSize size;       /* buffer size */
83     int  mode;          /* buffering mode (ScmPortBufferMode) & SIGPIPE flag */
84     ScmSize (*filler)(ScmPort *p, ScmSize min);
85     ScmSize (*flusher)(ScmPort *p, ScmSize cnt, int forcep);
86     void (*closer)(ScmPort *p);
87     int  (*ready)(ScmPort *p);
88     int  (*filenum)(ScmPort *p);
89     off_t (*seeker)(ScmPort *p, off_t offset, int whence);
90     void *data;
91 
92     /* The following fields are added in 0.9.10.  When you pass ScmPortBuffer
93        to the constructor, those fields are looked at only when you specify
94        SCM_PORT_WITH_POSITION.  They are needed to fully support srfi-192-style
95        port positioning.   See the Port Positioning Interface below. */
96     ScmObj (*getpos)(ScmPort *p);
97     void   (*setpos)(ScmPort *p, ScmObj pos);
98     u_long flags;               /* reserved */
99 } ScmPortBuffer;
100 
101 /* The function table of procedural port. */
102 typedef struct ScmPortVTableRec {
103     int     (*Getb)(ScmPort *p);
104     int     (*Getc)(ScmPort *p);
105     ScmSize (*Getz)(char *buf, ScmSize buflen, ScmPort *p);
106     int     (*Ready)(ScmPort *p, int charp);
107     void    (*Putb)(ScmByte b, ScmPort *p);
108     void    (*Putc)(ScmChar c, ScmPort *p);
109     void    (*Putz)(const char *buf, ScmSize size, ScmPort *p);
110     void    (*Puts)(ScmString *s, ScmPort *p);
111     void    (*Flush)(ScmPort *p);
112     void    (*Close)(ScmPort *p);
113     off_t   (*Seek)(ScmPort *p, off_t off, int whence);
114     void    *data;
115 
116     /* The following fields are added in 0.9.10.  When you pass ScmPortBuffer
117        to the constructor, those fields are looked at only when you specify
118        SCM_PORT_WITH_POSITION.  They are needed to fully support srfi-192-style
119        port positioning.   See the Port Positioning Interface below. */
120     ScmObj (*GetPos)(ScmPort *p);
121     void   (*SetPos)(ScmPort *p, ScmObj pos);
122     u_long flags;               /* reserved */
123 } ScmPortVTable;
124 
125 /* Input string port */
126 typedef struct ScmPortInputStringRec {
127     const char *start;
128     const char *current;
129     const char *end;
130 } ScmPortInputString;
131 
132 /* Note on Port Positioning Interface
133 
134    Gauche historically supported lseek(2) style interface, which can handle
135    both getting and setting the position.  R6RS introduced
136    port-position and set-port-position! interface, which then adopted as
137    SRFI-192.  It requires different strategy than lseek interface.
138 
139    1) SRFI-192 allows port position can be gotten but not be set, and that
140       needs to be queried by port-has-set-port-position!?.  With lseek API,
141       port position is either totally unavaiable or can be gotten/set.
142       (seek callback may raise an error when setting is not supported, but
143       it can't be queried.)
144 
145    2) SRFI-192 allows arbitrary Scheme object as the position, while lseek
146       API assumes integer byte offset.  Indeed, for the textual port, meaning
147       of byte offset is vague.
148 
149    3) Lseek allows position to be set relative to the current position or
150       to the end of the file.  SRFI-192 set-port-position! is always the
151       absolute position.
152 
153   To support both interface, we have these hooks in SCM_PORT_FILE and
154   SCM_PORT_PROC type of ports (the field names differ for the historical
155   reasons):
156 
157      off_t SEEK(ScmPort*, off_t, int)    ;; seeker, Seek
158      ScmObj GETPOS(ScmPort*)             ;; getpos, GetPos
159      void SETPOS(ScmPort*, ScmObj)       ;; setpos, SetPos
160 
161   GETPOS/SETPOS takes precedence to SEEK.
162 
163   Port is port-has-port-position? if it has either GETPOS or SEEK handler,
164   and port-has-set-port-position!? if it has either SETPOS or SEEK handler.
165 
166   For SCM_PORT_BUF, the position returned by GETPOS and that SETPOS takes
167   must be an exact Scheme integer, representing the integer byte offset.
168   Since the input is buffered, we need to calculate the actual position
169   in the buffer, from the source position returned by GETPOS.
170 
171   For SCM_PORT_PROC, we treat the position as an opaque object.  Note that
172   input port has a small buffer for peeked byte/character, that makes
173   things complicated.  Since we can't adjust the opaque position, we instead
174   call GETPOS before peek and remember the position.
175  */
176 
177 /*
178  * We don't expose much about ScmPort struct to the user.  A bunch of
179  * flags are public, but most of the stuff are hidden.  See priv/portP.h
180  * for the 'real' definition.
181  *
182  * ScmPort should never be allocated directly, or statically.  Port
183  * constructors properly initializes hidden fields.
184  */
185 
186 #define SCM_PORT_HEADER                                                 \
187     SCM_INSTANCE_HEADER;                                                \
188     u_int direction : 2;        /* SCM_PORT_INPUT or SCM_PORT_OUTPUT.   \
189                                    There may be I/O port in future. */  \
190     u_int type      : 2;        /* SCM_PORT_{FILE|ISTR|OSTR|PROC} */    \
191     u_int scrcnt    : 3;        /* # of bytes in the scratch buffer */  \
192                                                                         \
193     u_int ownerp    : 1;        /* TRUE if this port owns underlying    \
194                                    file pointer */                      \
195     u_int closed    : 1;        /* TRUE if this port is closed */       \
196     u_int error     : 1;        /* Error has been occurred */           \
197                                                                         \
198     u_int flags     : 5         /* see ScmPortFlags below */
199 
200 struct ScmPortRec {
201     SCM_PORT_HEADER;
202     /* See portP.h for the real definition.  The magic number is chosen
203        so that ScmPort has enough size to contain the real struct.
204 
205        We tested to use a pointer to the real struct, but I/O intensive
206        benchmark showed 2-3% reduction of speed.  So we avoid indirection.
207      */
208     char opaque[29*sizeof(ScmWord) + sizeof(ScmInternalFastlock)];
209 };
210 
211 /* Port direction.
212    Bidirectional port have both SCM_PORT_INPUT and SCM_PORT_OUTPUT bits set.
213    SCM_PORT_OUTPUT_TRANSIENT is only used for constructor to indicate
214    that the output buffer doesn't need to be flushed when the process
215    exits.  It is same as SCM_PORT_OUTPUT for non-buffered ports.
216    Only the lower two bits are stored in port->direction.
217  */
218 enum ScmPortDirection {
219     SCM_PORT_INPUT = 1,
220     SCM_PORT_OUTPUT = 2,
221     SCM_PORT_IOMASK = 3,
222     SCM_PORT_OUTPUT_TRANSIENT = 4+SCM_PORT_OUTPUT
223 };
224 
225 /* Port buffering mode */
226 enum ScmPortBufferMode {
227     SCM_PORT_BUFFER_FULL = 0,       /* full buffering */
228     SCM_PORT_BUFFER_LINE = 1,       /* flush the buffer for each line */
229     SCM_PORT_BUFFER_NONE = 2,       /* flush the buffer for every output */
230 
231     SCM_PORT_BUFFER_MODE_MASK = 0x07 /* for future extension */
232 };
233 
234 /* If this flag is set in `mode' member of ScmPortBuffer, SIGPIPE causes
235    the process to terminate.  By default this flag is off except stdin and
236    stdout ports; it is to emulate default Unix behavior.  On Windows platform
237    this flag is ignored, for we don't have SIGPIPE.  */
238 #define SCM_PORT_BUFFER_SIGPIPE_SENSITIVE  (1L<<8)
239 
240 /* Port types.  The type is also represented by a port's class, but
241    C routine can dispatch quicker using these flags.  User code
242    doesn't need to care about these. */
243 enum ScmPortType {
244     SCM_PORT_FILE,              /* file (buffered) port */
245     SCM_PORT_ISTR,              /* input string port */
246     SCM_PORT_OSTR,              /* output string port */
247     SCM_PORT_PROC               /* virtual port */
248 };
249 
250 /* Return value from Scm_FdReady */
251 enum ScmFdReadyResult {
252     SCM_FD_WOULDBLOCK,
253     SCM_FD_READY,
254     SCM_FD_UNKNOWN
255 };
256 
257 /* The flag bits passed to 'flags' argument of various port constructors */
258 enum ScmPortConstructorFlag {
259     SCM_PORT_OWNER = (1L<<0),        /* Set the ownerp flag of the port */
260     SCM_PORT_WITH_POSITION = (1L<<1) /* The additional getpos/setpos fields
261                                         are looked at. */
262 };
263 
264 /* Other flags used internally */
265 /* NB: The first two flags only matter when port->recursiveContext is set,
266    and they're transient by nature.  See write.c for the details. */
267 enum ScmPortFlags {
268     SCM_PORT_WRITESS = (1L<<0), /* we're write/ss mode.  */
269     SCM_PORT_WALKING = (1L<<1), /* indicates we're currently in 'walk' pass
270                                    of two-pass writing. */
271     SCM_PORT_PRIVATE = (1L<<2), /* this port is for 'private' use within
272                                    a thread, so never need to be locked. */
273     SCM_PORT_CASE_FOLD = (1L<<3),/* read from or write to this port should
274                                     be case folding. */
275     SCM_PORT_TRANSIENT = (1L<<4) /* a buffered output port that's used
276                                     transiently and doesn't need to be
277                                     registered for flushing. */
278 };
279 
280 /*================================================================
281  * Generic operations
282  */
283 
284 /* Predicates & accessors */
285 #define SCM_PORTP(obj)          (SCM_ISA(obj, SCM_CLASS_PORT))
286 
287 #define SCM_PORT(obj)           ((ScmPort *)(obj))
288 #define SCM_PORT_TYPE(obj)      (SCM_PORT(obj)->type)
289 #define SCM_PORT_DIR(obj)       (SCM_PORT(obj)->direction)
290 #define SCM_PORT_FLAGS(obj)     (SCM_PORT(obj)->flags)
291 
292 #define SCM_PORT_CASE_FOLDING(obj) (SCM_PORT_FLAGS(obj)&SCM_PORT_CASE_FOLD)
293 
294 #define SCM_PORT_CLOSED_P(obj)  (SCM_PORT(obj)->closed)
295 #define SCM_PORT_OWNER_P(obj)   (SCM_PORT(obj)->ownerp)
296 #define SCM_PORT_ERROR_OCCURRED_P(obj) (SCM_PORT(obj)->error)
297 
298 #define SCM_IPORTP(obj)  (SCM_PORTP(obj)&&(SCM_PORT_DIR(obj)&SCM_PORT_INPUT))
299 #define SCM_OPORTP(obj)  (SCM_PORTP(obj)&&(SCM_PORT_DIR(obj)&SCM_PORT_OUTPUT))
300 
301 /* The following macros are for the backward compatibility; their use is
302    deprecated.  (We used to have these macros directly access ScmPort
303    structure to eliminate function call overhead.  It turned out
304    it matters little.   Use function APIs.) */
305 #define SCM_PUTB(b, p)     Scm_Putb(b, SCM_PORT(p))
306 #define SCM_PUTC(c, p)     Scm_Putc(c, SCM_PORT(p))
307 #define SCM_PUTZ(s, l, p)  Scm_Putz(s, l, SCM_PORT(p))
308 #define SCM_PUTS(s, p)     Scm_Puts(SCM_STRING(s), SCM_PORT(p))
309 #define SCM_FLUSH(p)       Scm_Flush(SCM_PORT(p))
310 #define SCM_PUTNL(p)       SCM_PUTC('\n', p)
311 #define SCM_UNGETC(c, port) Scm_Ungetc(c, SCM_PORT(port))
312 #define SCM_GETB(b, p)     (b = Scm_Getb(SCM_PORT(p)))
313 #define SCM_GETC(c, p)     (c = Scm_Getc(SCM_PORT(p)))
314 #define SCM_PORT_BUFFER_ROOM(p)  Scm_PortBufferRoom(p)
315 #define SCM_PORT_BUFFER_AVAIL(p) Scm_PortBufferAvail(p)
316 
317 
318 SCM_CLASS_DECL(Scm_PortClass);
319 #define SCM_CLASS_PORT                (&Scm_PortClass)
320 
321 SCM_CLASS_DECL(Scm_CodingAwarePortClass);
322 #define SCM_CLASS_CODING_AWARE_PORT   (&Scm_CodingAwarePortClass)
323 
324 /* Conversion between Scheme keyword and ScmPortBufferMode enums */
325 SCM_EXTERN ScmObj Scm_GetPortBufferingModeAsKeyword(ScmPort *port);
326 SCM_EXTERN int    Scm_BufferingModeAsKeyword(ScmObj flag,
327                                              int direction,
328                                              int fallback);
329 
330 SCM_EXTERN ScmObj Scm_GetBufferingMode(ScmPort *port); /* obsoleted */
331 SCM_EXTERN int    Scm_BufferingMode(ScmObj flag,       /* obsoleted */
332                                     int direction,
333                                     int fallback);
334 
335 SCM_EXTERN int    Scm_GetPortBufferingMode(ScmPort *port);
336 SCM_EXTERN void   Scm_SetPortBufferingMode(ScmPort *port, int mode);
337 SCM_EXTERN int    Scm_GetPortBufferSigpipeSensitive(ScmPort *port);
338 SCM_EXTERN void   Scm_SetPortBufferSigpipeSensitive(ScmPort *port, int sensitive);
339 SCM_EXTERN int    Scm_GetPortCaseFolding(ScmPort *port);
340 SCM_EXTERN void   Scm_SetPortCaseFolding(ScmPort *port, int flag);
341 SCM_EXTERN ScmObj Scm_GetPortReaderLexicalMode(ScmPort *port);
342 SCM_EXTERN void   Scm_SetPortReaderLexicalMode(ScmPort *port, ScmObj obj);
343 
344 SCM_EXTERN void   Scm_SetPortErrorOccurred(ScmPort *port, int val);
345 
346 SCM_EXTERN int    Scm_PortPositionable(ScmPort *port, int setp);
347 
348 SCM_EXTERN void   Scm_FlushAllPorts(int exitting);
349 
350 SCM_EXTERN ScmObj Scm_PortName(ScmPort *port);
351 SCM_EXTERN ScmSize Scm_PortLine(ScmPort *port);
352 SCM_EXTERN ScmSize Scm_PortBytes(ScmPort *port);
353 SCM_EXTERN ScmObj Scm_GetPortPosition(ScmPort *port);
354 SCM_EXTERN ScmObj Scm_GetPortPositionUnsafe(ScmPort *port);
355 SCM_EXTERN ScmObj Scm_SetPortPosition(ScmPort *port, ScmObj pos);
356 SCM_EXTERN ScmObj Scm_PortSeek(ScmPort *port, ScmObj off, int whence);
357 SCM_EXTERN ScmObj Scm_PortSeekUnsafe(ScmPort *port, ScmObj off, int whence);
358 SCM_EXTERN int    Scm_PortFileNo(ScmPort *port);
359 SCM_EXTERN void   Scm_PortFdDup(ScmPort *dst, ScmPort *src);
360 SCM_EXTERN int    Scm_FdReady(int fd, int dir);
361 SCM_EXTERN int    Scm_ByteReady(ScmPort *port);
362 SCM_EXTERN int    Scm_ByteReadyUnsafe(ScmPort *port);
363 SCM_EXTERN int    Scm_CharReady(ScmPort *port);
364 SCM_EXTERN int    Scm_CharReadyUnsafe(ScmPort *port);
365 
366 SCM_EXTERN ScmPortBuffer      *Scm_PortBufferStruct(ScmPort *port);
367 SCM_EXTERN ScmPortInputString *Scm_PortInputStringStruct(ScmPort *port);
368 SCM_EXTERN ScmDString         *Scm_PortOutputDString(ScmPort *port);
369 SCM_EXTERN ScmPortVTable      *Scm_PortVTableStruct(ScmPort *port);
370 
371 SCM_EXTERN ScmSize  Scm_PortBufferRoom(ScmPort *port);
372 SCM_EXTERN ScmSize  Scm_PortBufferAvail(ScmPort *port);
373 
374 SCM_EXTERN ScmWriteState *Scm_PortWriteState(ScmPort *);
375 SCM_EXTERN void           Scm_PortWriteStateSet(ScmPort *, ScmWriteState*);
376 
377 SCM_EXTERN void   Scm_ClosePort(ScmPort *port);
378 
379 SCM_EXTERN ScmObj Scm_VMWithPortLocking(ScmPort *port,
380                                         ScmObj closure);
381 
382 SCM_EXTERN ScmObj Scm_PortAttrGet(ScmPort *port, ScmObj key,
383                                   ScmObj fallback);
384 SCM_EXTERN ScmObj Scm_PortAttrGetUnsafe(ScmPort *port, ScmObj key,
385                                         ScmObj fallback);
386 SCM_EXTERN ScmObj Scm_PortAttrSet(ScmPort *port, ScmObj key, ScmObj val);
387 SCM_EXTERN ScmObj Scm_PortAttrSetUnsafe(ScmPort *port, ScmObj key, ScmObj val);
388 SCM_EXTERN ScmObj Scm_PortAttrCreate(ScmPort *port, ScmObj key, ScmObj get, ScmObj set);
389 SCM_EXTERN ScmObj Scm_PortAttrCreateUnsafe(ScmPort *port, ScmObj key, ScmObj get, ScmObj set);
390 SCM_EXTERN ScmObj Scm_PortAttrDelete(ScmPort *port, ScmObj key);
391 SCM_EXTERN ScmObj Scm_PortAttrDeleteUnsafe(ScmPort *port, ScmObj key);
392 SCM_EXTERN ScmObj Scm_PortAttrs(ScmPort *port);
393 SCM_EXTERN ScmObj Scm_PortAttrsUnsafe(ScmPort *port);
394 
395 SCM_EXTERN void   Scm_Putb(ScmByte b, ScmPort *port);
396 SCM_EXTERN void   Scm_Putc(ScmChar c, ScmPort *port);
397 SCM_EXTERN void   Scm_Puts(ScmString *s, ScmPort *port);
398 SCM_EXTERN void   Scm_Putz(const char *s, ScmSize len, ScmPort *port);
399 SCM_EXTERN void   Scm_Flush(ScmPort *port);
400 
401 SCM_EXTERN void   Scm_PutbUnsafe(ScmByte b, ScmPort *port);
402 SCM_EXTERN void   Scm_PutcUnsafe(ScmChar c, ScmPort *port);
403 SCM_EXTERN void   Scm_PutsUnsafe(ScmString *s, ScmPort *port);
404 SCM_EXTERN void   Scm_PutzUnsafe(const char *s, ScmSize len, ScmPort *port);
405 SCM_EXTERN void   Scm_FlushUnsafe(ScmPort *port);
406 
407 SCM_EXTERN void   Scm_Ungetc(ScmChar ch, ScmPort *port);
408 SCM_EXTERN void   Scm_Ungetb(int b, ScmPort *port);
409 SCM_EXTERN int    Scm_Getb(ScmPort *port);
410 SCM_EXTERN int    Scm_Getc(ScmPort *port);
411 SCM_EXTERN ScmSize Scm_Getz(char *buf, ScmSize buflen, ScmPort *port);
412 SCM_EXTERN ScmChar Scm_Peekc(ScmPort *port);
413 SCM_EXTERN int    Scm_Peekb(ScmPort *port);
414 SCM_EXTERN ScmObj Scm_UngottenChars(ScmPort *port);
415 SCM_EXTERN ScmObj Scm_UngottenBytes(ScmPort *port);
416 
417 SCM_EXTERN void   Scm_UngetcUnsafe(ScmChar ch, ScmPort *port);
418 SCM_EXTERN void   Scm_UngetbUnsafe(int b, ScmPort *port);
419 SCM_EXTERN int    Scm_GetbUnsafe(ScmPort *port);
420 SCM_EXTERN int    Scm_GetcUnsafe(ScmPort *port);
421 SCM_EXTERN ScmSize Scm_GetzUnsafe(char *buf, ScmSize buflen, ScmPort *port);
422 SCM_EXTERN ScmChar Scm_PeekcUnsafe(ScmPort *port);
423 SCM_EXTERN int    Scm_PeekbUnsafe(ScmPort *port);
424 SCM_EXTERN ScmObj Scm_UngottenCharsUnsafe(ScmPort *port);
425 SCM_EXTERN ScmObj Scm_UngottenBytesUnsafe(ScmPort *port);
426 
427 SCM_EXTERN ScmObj Scm_ReadLine(ScmPort *port);
428 SCM_EXTERN ScmObj Scm_ReadLineUnsafe(ScmPort *port);
429 
430 /*================================================================
431  * File ports
432  */
433 
434 SCM_EXTERN ScmObj Scm_OpenFilePort(const char *path, int flags,
435                                    int buffering, int perm);
436 
437 SCM_EXTERN ScmObj Scm_Stdin(void);
438 SCM_EXTERN ScmObj Scm_Stdout(void);
439 SCM_EXTERN ScmObj Scm_Stderr(void);
440 
441 SCM_EXTERN ScmObj Scm_SetStdin(ScmPort *port);
442 SCM_EXTERN ScmObj Scm_SetStdout(ScmPort *port);
443 SCM_EXTERN ScmObj Scm_SetStderr(ScmPort *port);
444 
445 #define SCM_CURIN    SCM_VM_CURRENT_INPUT_PORT(Scm_VM())
446 #define SCM_CUROUT   SCM_VM_CURRENT_OUTPUT_PORT(Scm_VM())
447 #define SCM_CURERR   SCM_VM_CURRENT_ERROR_PORT(Scm_VM())
448 
449 SCM_EXTERN ScmObj Scm_SetCurrentInputPort(ScmPort *port);
450 SCM_EXTERN ScmObj Scm_SetCurrentOutputPort(ScmPort *port);
451 SCM_EXTERN ScmObj Scm_SetCurrentErrorPort(ScmPort *port);
452 
453 /*================================================================
454  * String ports
455  */
456 
457 enum {
458     SCM_PORT_STRING_PRIVATE = 1 /* for flags arg */
459 };
460 
461 SCM_EXTERN ScmObj Scm_MakeInputStringPortFull(ScmString *str,
462                                               ScmObj name,
463                                               u_long flags);
464 SCM_EXTERN ScmObj Scm_MakeOutputStringPortFull(ScmObj name,
465                                                u_long flags);
466 
467 /* these two are deprecated */
468 SCM_EXTERN ScmObj Scm_MakeInputStringPort(ScmString *str, int privatep);
469 SCM_EXTERN ScmObj Scm_MakeOutputStringPort(int privatep);
470 
471 SCM_EXTERN ScmObj Scm_GetOutputString(ScmPort *port, int flags);
472 SCM_EXTERN ScmObj Scm_GetOutputStringUnsafe(ScmPort *port, int flags);
473 SCM_EXTERN ScmObj Scm_GetRemainingInputString(ScmPort *port, int flags);
474 
475 /*================================================================
476  * Other type of ports
477  */
478 
479 SCM_EXTERN ScmObj Scm_MakeVirtualPortFull(ScmClass *klass,
480                                           ScmObj name, int direction,
481                                           const ScmPortVTable *vtable,
482                                           u_long flags);
483 
484 /* deprecated */
485 SCM_EXTERN ScmObj Scm_MakeVirtualPort(ScmClass *klass,
486                                       int direction,
487                                       const ScmPortVTable *vtable);
488 
489 
490 SCM_EXTERN ScmObj Scm_MakeBufferedPortFull(ScmClass *klass,
491                                            ScmObj name, int direction,
492                                            ScmPortBuffer *bufrec,
493                                            u_long flags);
494 
495 /* deprecated */
496 SCM_EXTERN ScmObj Scm_MakeBufferedPort(ScmClass *klass,
497                                        ScmObj name, int direction,
498                                        int ownerp,
499                                        ScmPortBuffer *bufrec);
500 
501 SCM_EXTERN ScmObj Scm_MakePortWithFd(ScmObj name,
502                                      int direction,
503                                      int fd,
504                                      int bufmode,
505                                      int ownerp);
506 SCM_EXTERN ScmObj Scm_MakeCodingAwarePort(ScmPort *iport);
507 
508 #endif /*GAUCHE_PORT_H*/
509 
510