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:
parent
264e9cbc93
commit
60d02d0914
4 changed files with 70 additions and 85 deletions
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue