read-delimited sequence stream &key start end delimiter test key => position, delimited-p
Arguments and Values:
stream---an input stream.
start, end---bounding index designators of sequence. The defaults for start and end are 0 and nil, respectively.
delimiter---a character. It defaults to #\newline.
test---a designator for a function of two arguments that returns a generalized boolean.
key---a designator for a function of one argument, or nil.
position---an integer greater than or equal to zero, and less than or equal to the length of the sequence.
delimited-p---the result of the last invokation of test
Destructively modifies sequence by replacing elements of sequence bounded by start and end with elements read from stream.
Test is called with the actual read character, converted by applying key to it, as the first and delimiter as the second argument.
If a character is read for which (funcall test (funcall key char) delimiter) is non-nil, read-delimited terminates the copying even before reaching end of file or the end of the bounding designator.
read-delimited returns the index of the first element of sequence that was not updated as the first and the result of the last invokation of test as the second value.
Sequence is destructively modified by copying successive elements into it from stream. If the end of file for stream is reached before copying all elements of the subsequence, then the extra elements near the end of sequence are not updated.
If start and/or end are out of bounds, or if start > end, then a read-delimited-bounds-error error is signalled. This error is passed the values of start, end, and sequence, which can be read with read-delimited-bounds-error-start, read-delimited-bounds-error-end, and read-delimited-bounds-error-sequence, respectively.
This is one of the more complex utilities, and the amount of argument checking needed to do it properly is daunting. An amazing 76% of the code is spent on making sure that the bounds are valid and in order, and on what to do if they aren't. Once you remove all that, the actual function which does all the work is quite simple, and unlikely to contain bugs.
The design of this function makes it a little annoying to use, but it is more efficient. If you need something more high-level, this could be built on top of read-delimited fairly easily.