1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-20 11:40:18 +02:00

Move setvbuf impl to ports.[ch]

* libguile/fports.h (scm_setbuf0): Remove extraneous declaration.
* libguile/fports.c:
* libguile/ports.c:
* libguile/ports.c (scm_setvbuf): Move setvbuf to ports.[ch].
  (scm_init_ports): Move _IONBF, _IOLBF, _IOFBF definitions here.
This commit is contained in:
Andy Wingo 2016-04-01 22:37:41 +02:00
parent 8a0fc51176
commit 0a0a8d819d
4 changed files with 104 additions and 105 deletions

View file

@ -136,105 +136,6 @@ scm_fport_buffer_add (SCM port, long read_size, long write_size)
}
#undef FUNC_NAME
SCM_DEFINE (scm_setvbuf, "setvbuf", 2, 1, 0,
(SCM port, SCM mode, SCM size),
"Set the buffering mode for @var{port}. @var{mode} can be:\n"
"@table @code\n"
"@item _IONBF\n"
"non-buffered\n"
"@item _IOLBF\n"
"line buffered\n"
"@item _IOFBF\n"
"block buffered, using a newly allocated buffer of @var{size} bytes.\n"
"If @var{size} is omitted, a default size will be used.\n"
"@end table\n\n"
"Only certain types of ports are supported, most importantly\n"
"file ports.")
#define FUNC_NAME s_scm_setvbuf
{
int cmode;
long csize;
size_t ndrained;
char *drained = NULL;
scm_t_port *pt;
scm_t_ptob_descriptor *ptob;
port = SCM_COERCE_OUTPORT (port);
SCM_VALIDATE_OPENPORT (1, port);
ptob = SCM_PORT_DESCRIPTOR (port);
if (ptob->setvbuf == NULL)
scm_wrong_type_arg_msg (FUNC_NAME, 1, port,
"port that supports 'setvbuf'");
cmode = scm_to_int (mode);
if (cmode != _IONBF && cmode != _IOFBF && cmode != _IOLBF)
scm_out_of_range (FUNC_NAME, mode);
if (cmode == _IOLBF)
{
SCM_SET_CELL_WORD_0 (port, SCM_CELL_WORD_0 (port) | SCM_BUFLINE);
cmode = _IOFBF;
}
else
SCM_SET_CELL_WORD_0 (port,
SCM_CELL_WORD_0 (port) & ~(scm_t_bits) SCM_BUFLINE);
if (SCM_UNBNDP (size))
{
if (cmode == _IOFBF)
csize = -1;
else
csize = 0;
}
else
{
csize = scm_to_int (size);
if (csize < 0 || (cmode == _IONBF && csize > 0))
scm_out_of_range (FUNC_NAME, size);
}
pt = SCM_PTAB_ENTRY (port);
if (SCM_INPUT_PORT_P (port))
{
/* Drain pending input from PORT. Don't use `scm_drain_input' since
it returns a string, whereas we want binary input here. */
ndrained = pt->read_end - pt->read_pos;
if (pt->read_buf == pt->putback_buf)
ndrained += pt->saved_read_end - pt->saved_read_pos;
if (ndrained > 0)
{
drained = scm_gc_malloc_pointerless (ndrained, "file port");
scm_take_from_input_buffers (port, drained, ndrained);
}
}
else
ndrained = 0;
if (SCM_OUTPUT_PORT_P (port))
scm_flush_unlocked (port);
if (pt->read_buf == pt->putback_buf)
{
pt->read_buf = pt->saved_read_buf;
pt->read_pos = pt->saved_read_pos;
pt->read_end = pt->saved_read_end;
pt->read_buf_size = pt->saved_read_buf_size;
}
ptob->setvbuf (port, csize, csize);
if (ndrained > 0)
/* Put DRAINED back to PORT. */
scm_unget_bytes ((unsigned char *) drained, ndrained, port);
return SCM_UNSPECIFIED;
}
#undef FUNC_NAME
/* Move ports with the specified file descriptor to new descriptors,
* resetting the revealed count to 0.
*/
@ -1000,10 +901,6 @@ scm_init_fports ()
{
scm_tc16_fport = scm_make_fptob ();
scm_c_define ("_IOFBF", scm_from_int (_IOFBF));
scm_c_define ("_IOLBF", scm_from_int (_IOLBF));
scm_c_define ("_IONBF", scm_from_int (_IONBF));
sys_file_port_name_canonicalization = scm_make_fluid ();
scm_c_define ("%file-port-name-canonicalization",
sys_file_port_name_canonicalization);

View file

@ -51,8 +51,6 @@ SCM_API scm_t_bits scm_tc16_fport;
#define SCM_FDES_RANDOM_P(fdes) ((lseek (fdes, 0, SEEK_CUR) == -1) ? 0 : 1)
SCM_API SCM scm_setbuf0 (SCM port);
SCM_API SCM scm_setvbuf (SCM port, SCM mode, SCM size);
SCM_API void scm_evict_ports (int fd);
SCM_API SCM scm_open_file_with_encoding (SCM filename, SCM modes,
SCM guess_encoding, SCM encoding);

View file

@ -2337,6 +2337,105 @@ scm_port_non_buffer (scm_t_port *pt)
pt->write_end = pt->write_buf + pt->write_buf_size;
}
SCM_DEFINE (scm_setvbuf, "setvbuf", 2, 1, 0,
(SCM port, SCM mode, SCM size),
"Set the buffering mode for @var{port}. @var{mode} can be:\n"
"@table @code\n"
"@item _IONBF\n"
"non-buffered\n"
"@item _IOLBF\n"
"line buffered\n"
"@item _IOFBF\n"
"block buffered, using a newly allocated buffer of @var{size} bytes.\n"
"If @var{size} is omitted, a default size will be used.\n"
"@end table\n\n"
"Only certain types of ports are supported, most importantly\n"
"file ports.")
#define FUNC_NAME s_scm_setvbuf
{
int cmode;
long csize;
size_t ndrained;
char *drained = NULL;
scm_t_port *pt;
scm_t_ptob_descriptor *ptob;
port = SCM_COERCE_OUTPORT (port);
SCM_VALIDATE_OPENPORT (1, port);
ptob = SCM_PORT_DESCRIPTOR (port);
if (ptob->setvbuf == NULL)
scm_wrong_type_arg_msg (FUNC_NAME, 1, port,
"port that supports 'setvbuf'");
cmode = scm_to_int (mode);
if (cmode != _IONBF && cmode != _IOFBF && cmode != _IOLBF)
scm_out_of_range (FUNC_NAME, mode);
if (cmode == _IOLBF)
{
SCM_SET_CELL_WORD_0 (port, SCM_CELL_WORD_0 (port) | SCM_BUFLINE);
cmode = _IOFBF;
}
else
SCM_SET_CELL_WORD_0 (port,
SCM_CELL_WORD_0 (port) & ~(scm_t_bits) SCM_BUFLINE);
if (SCM_UNBNDP (size))
{
if (cmode == _IOFBF)
csize = -1;
else
csize = 0;
}
else
{
csize = scm_to_int (size);
if (csize < 0 || (cmode == _IONBF && csize > 0))
scm_out_of_range (FUNC_NAME, size);
}
pt = SCM_PTAB_ENTRY (port);
if (SCM_INPUT_PORT_P (port))
{
/* Drain pending input from PORT. Don't use `scm_drain_input' since
it returns a string, whereas we want binary input here. */
ndrained = pt->read_end - pt->read_pos;
if (pt->read_buf == pt->putback_buf)
ndrained += pt->saved_read_end - pt->saved_read_pos;
if (ndrained > 0)
{
drained = scm_gc_malloc_pointerless (ndrained, "file port");
scm_take_from_input_buffers (port, drained, ndrained);
}
}
else
ndrained = 0;
if (SCM_OUTPUT_PORT_P (port))
scm_flush_unlocked (port);
if (pt->read_buf == pt->putback_buf)
{
pt->read_buf = pt->saved_read_buf;
pt->read_pos = pt->saved_read_pos;
pt->read_end = pt->saved_read_end;
pt->read_buf_size = pt->saved_read_buf_size;
}
ptob->setvbuf (port, csize, csize);
if (ndrained > 0)
/* Put DRAINED back to PORT. */
scm_unget_bytes ((unsigned char *) drained, ndrained, port);
return SCM_UNSPECIFIED;
}
#undef FUNC_NAME
/* this should only be called when the read buffer is empty. it
tries to refill the read buffer. it returns the first char from
the port, which is either EOF or *(pt->read_pos). */
@ -3183,6 +3282,10 @@ scm_init_ports ()
scm_c_define ("SEEK_CUR", scm_from_int (SEEK_CUR));
scm_c_define ("SEEK_END", scm_from_int (SEEK_END));
scm_c_define ("_IOFBF", scm_from_int (_IOFBF));
scm_c_define ("_IOLBF", scm_from_int (_IOLBF));
scm_c_define ("_IONBF", scm_from_int (_IONBF));
scm_tc16_void_port = scm_make_port_type ("void", fill_input_void_port,
write_void_port);

View file

@ -338,6 +338,7 @@ SCM_API SCM scm_unread_string (SCM str, SCM port);
/* Manipulating the buffers. */
SCM_API void scm_port_non_buffer (scm_t_port *pt);
SCM_API SCM scm_setvbuf (SCM port, SCM mode, SCM size);
SCM_API int scm_fill_input (SCM port);
SCM_API int scm_fill_input_unlocked (SCM port);
SCM_INTERNAL size_t scm_take_from_input_buffers (SCM port, char *dest, size_t read_len);