1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-20 03:30:27 +02:00

* validate.h (SCM_VALIDATE_SUBSTRING_SPEC_COPY): new macro.

* ioext.c (scm_read_string_x_partial, scm_read_delimited_x),
	socket.c (scm_recvfrom): use the new macro, plus minor docstring
	changes.
	* ioext.c (scm_read_string_x_partial): don't crash if -1 is supplied
	for fdes.  if current input port is used, check that it's a file
	port.
This commit is contained in:
Gary Houston 2001-01-08 23:10:06 +00:00
parent 264e9cbc93
commit 60d02d0914
4 changed files with 70 additions and 85 deletions

View file

@ -1,3 +1,13 @@
2001-01-08 Gary Houston <ghouston@arglist.com>
* validate.h (SCM_VALIDATE_SUBSTRING_SPEC_COPY): new macro.
* ioext.c (scm_read_string_x_partial, scm_read_delimited_x),
socket.c (scm_recvfrom): use the new macro, plus minor docstring
changes.
* ioext.c (scm_read_string_x_partial): don't crash if -1 is supplied
for fdes. if current input port is used, check that it's a file
port.
2001-01-06 Gary Houston <ghouston@arglist.com>
* ioext.c (scm_read_string_x_partial): new procedure, implements

View file

@ -105,51 +105,38 @@ SCM_DEFINE (scm_read_string_x_partial, "read-string!/partial", 1, 3, 0,
char *dest;
long read_len;
long chars_read = 0;
int fdes = -1;
SCM port = SCM_BOOL_F;
SCM_VALIDATE_STRING_COPY (1, str, dest);
if (SCM_UNBNDP (port_or_fdes))
port = scm_cur_inp;
else if (SCM_INUMP (port_or_fdes))
fdes = SCM_INUM (port_or_fdes);
else
{
SCM_VALIDATE_OPFPORT (2, port_or_fdes);
SCM_VALIDATE_INPUT_PORT (2, port_or_fdes);
port = port_or_fdes;
}
int fdes;
{
long string_len = SCM_STRING_LENGTH (str);
long offset = SCM_NUM2LONG_DEF (3, start, 0);
long last = SCM_NUM2LONG_DEF (4, end, string_len);
if (offset < 0 || offset > string_len)
SCM_OUT_OF_RANGE (3, start);
if (last < offset || last > string_len)
SCM_OUT_OF_RANGE (4, end);
long offset;
long last;
SCM_VALIDATE_SUBSTRING_SPEC_COPY (1, str, dest, 3, start, offset,
4, end, last);
dest += offset;
read_len = last - offset;
}
if (fdes == -1)
if (SCM_INUMP (port_or_fdes))
fdes = SCM_INUM (port_or_fdes);
else
{
/* if there's anything in the port buffers, use it. but if
something is read from the buffers, don't touch the file
descriptor. otherwise the "return immediately if something
is available" rule may be violated. */
chars_read = scm_take_from_input_buffers (port, dest, read_len);
SCM port = SCM_UNBNDP (port_or_fdes) ? scm_cur_inp : port_or_fdes;
SCM_VALIDATE_OPFPORT (2, port);
SCM_VALIDATE_INPUT_PORT (2, port);
/* if there's anything in the port buffers, use it, but then
don't touch the file descriptor. otherwise the
"return immediately if something is available" rule may
be violated. */
chars_read = scm_take_from_input_buffers (port, dest, read_len);
fdes = SCM_FPORT_FDES (port);
}
if (chars_read == 0 && read_len > 0) /* don't confuse read_len == 0 with
EOF. */
{
if (fdes == -1)
fdes = SCM_FPORT_FDES (port);
SCM_SYSCALL (chars_read = read (fdes, dest, read_len));
if (chars_read == -1)
{
@ -174,46 +161,39 @@ SCM_DEFINE (scm_read_string_x_partial, "read-string!/partial", 1, 3, 0,
#undef FUNC_NAME
SCM_DEFINE (scm_read_delimited_x, "%read-delimited!", 3, 3, 0,
(SCM delims, SCM buf, SCM gobble, SCM port, SCM start, SCM end),
"Read characters from @var{port} into @var{buf} until one of the\n"
"characters in the @var{delims} string is encountered. If @var{gobble?}\n"
"is true, store the delimiter character in @var{buf} as well; otherwise,\n"
"discard it. If @var{port} is not specified, use the value of\n"
(SCM delims, SCM str, SCM gobble, SCM port, SCM start, SCM end),
"Read characters from @var{port} into @var{str} until one of the\n"
"characters in the @var{delims} string is encountered. If @var{gobble}\n"
"is true, discard the delimiter character; otherwise, leave it\n"
"in the input stream for the next read.\n"
"If @var{port} is not specified, use the value of\n"
"@code{(current-input-port)}. If @var{start} or @var{end} are specified,\n"
"store data only into the substring of @var{buf} bounded by @var{start}\n"
"and @var{end} (which default to the beginning and end of the buffer,\n"
"store data only into the substring of @var{str} bounded by @var{start}\n"
"and @var{end} (which default to the beginning and end of the string,\n"
"respectively).\n\n"
"Return a pair consisting of the delimiter that terminated the string and\n"
"the number of characters read. If reading stopped at the end of file,\n"
"the delimiter returned is the @var{eof-object}; if the buffer was filled\n"
"the delimiter returned is the @var{eof-object}; if the string was filled\n"
"without encountering a delimiter, this value is @var{#f}.")
#define FUNC_NAME s_scm_read_delimited_x
{
long j;
char *cbuf;
char *buf;
long cstart;
long cend, tend;
long cend;
int c;
char *cdelims;
int num_delims;
SCM_VALIDATE_STRING_COPY (1, delims, cdelims);
num_delims = SCM_STRING_LENGTH (delims);
SCM_VALIDATE_STRING_COPY (2,buf,cbuf);
cend = SCM_STRING_LENGTH (buf);
SCM_VALIDATE_SUBSTRING_SPEC_COPY (2, str, buf, 5, start, cstart,
6, end, cend);
if (SCM_UNBNDP (port))
port = scm_cur_inp;
else
SCM_VALIDATE_OPINPORT (4,port);
SCM_VALIDATE_INUM_DEF_COPY (5,start,0,cstart);
SCM_ASSERT_RANGE(5, start, cstart >= 0 && cstart < cend);
SCM_VALIDATE_INUM_DEF_COPY (6,end,cend,tend);
SCM_ASSERT_RANGE(6, end, tend > cstart && tend <= cend);
cend = tend;
for (j = cstart; j < cend; j++)
{
int k;
@ -234,7 +214,7 @@ SCM_DEFINE (scm_read_delimited_x, "%read-delimited!", 3, 3, 0,
return scm_cons (SCM_EOF_VAL,
scm_long2num (j - cstart));
cbuf[j] = c;
buf[j] = c;
}
return scm_cons (SCM_BOOL_F, scm_long2num (j - cstart));
}

View file

@ -746,12 +746,12 @@ SCM_DEFINE (scm_send, "send", 2, 1, 0,
#undef FUNC_NAME
SCM_DEFINE (scm_recvfrom, "recvfrom!", 2, 3, 0,
(SCM sock, SCM buf, SCM flags, SCM start, SCM end),
(SCM sock, SCM str, SCM flags, SCM start, SCM end),
"Returns data from the socket port @var{socket} and also information about\n"
"where the data was received from. @var{socket} must already\n"
"be bound to the address from which data is to be received.\n"
"@code{buf}, is a string into which\n"
"the data will be written. The size of @var{buf} limits the amount of\n"
"@code{str}, is a string into which\n"
"the data will be written. The size of @var{str} limits the amount of\n"
"data which can be received: in the case of packet\n"
"protocols, if a packet larger than this limit is encountered then some data\n"
"will be irrevocably lost.\n\n"
@ -760,7 +760,7 @@ SCM_DEFINE (scm_recvfrom, "recvfrom!", 2, 3, 0,
"The value returned is a pair: the CAR is the number of bytes read from\n"
"the socket and the CDR an address object in the same form as returned by\n"
"@code{accept}.\n\n"
"The @var{start} and @var{end} arguments specify a substring of @var{buf}\n"
"The @var{start} and @var{end} arguments specify a substring of @var{str}\n"
"to which the data should be written.\n\n"
"Note that the data is read directly from the socket file descriptor:\n"
"any unread buffered port data is ignored.")
@ -769,44 +769,23 @@ SCM_DEFINE (scm_recvfrom, "recvfrom!", 2, 3, 0,
int rv;
int fd;
int flg;
int offset = 0;
char *buf;
int offset;
int cend;
size_t tmp_size;
SCM address;
SCM_VALIDATE_OPFPORT (1,sock);
SCM_VALIDATE_STRING (2,buf);
cend = SCM_STRING_LENGTH (buf);
fd = SCM_FPORT_FDES (sock);
SCM_VALIDATE_SUBSTRING_SPEC_COPY (2, str, buf, 4, start, offset,
5, end, cend);
if (SCM_UNBNDP (flags))
flg = 0;
else
{
flg = SCM_NUM2ULONG (3,flags);
if (!SCM_UNBNDP (start))
{
offset = (int) SCM_NUM2LONG (4,start);
if (offset < 0 || offset >= cend)
SCM_OUT_OF_RANGE (4, start);
if (!SCM_UNBNDP (end))
{
int tend = (int) SCM_NUM2LONG (5,end);
if (tend <= offset || tend > cend)
SCM_OUT_OF_RANGE (5, end);
cend = tend;
}
}
}
fd = SCM_FPORT_FDES (sock);
SCM_VALIDATE_ULONG_COPY (3, flags, flg);
tmp_size = scm_addr_buffer_size;
SCM_SYSCALL (rv = recvfrom (fd, SCM_STRING_CHARS (buf) + offset,
SCM_SYSCALL (rv = recvfrom (fd, buf + offset,
cend - offset, flg,
(struct sockaddr *) scm_addr_buffer,
&tmp_size));

View file

@ -1,4 +1,4 @@
/* $Id: validate.h,v 1.23 2001-01-06 18:46:48 mvo Exp $ */
/* $Id: validate.h,v 1.24 2001-01-08 23:10:06 ghouston Exp $ */
/* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
*
* This program is free software; you can redistribute it and/or modify
@ -135,6 +135,22 @@
cvar = SCM_STRING_CHARS(str); \
} while (0)
/* validate a string and optional start/end arguments which default to
0/string-len. this is unrelated to the old shared substring
support, so please do not deprecate it :) */
#define SCM_VALIDATE_SUBSTRING_SPEC_COPY(pos_str, str, c_str, \
pos_start, start, c_start,\
pos_end, end, c_end) \
do {\
SCM_VALIDATE_STRING_COPY (pos_str, str, c_str);\
SCM_VALIDATE_INUM_DEF_COPY (pos_start, start, 0, c_start);\
SCM_VALIDATE_INUM_DEF_COPY (pos_end, end, SCM_STRING_LENGTH (str), c_end);\
SCM_ASSERT_RANGE (pos_start, start,\
0 <= c_start && c_start <= SCM_STRING_LENGTH (str));\
SCM_ASSERT_RANGE (pos_end, end,\
c_start <= c_end && c_end <= SCM_STRING_LENGTH (str));\
} while (0)
#define SCM_VALIDATE_REAL(pos, z) SCM_MAKE_VALIDATE (pos, z, REALP)
#define SCM_VALIDATE_NUMBER(pos, z) SCM_MAKE_VALIDATE (pos, z, NUMBERP)