Update documentation. Fix bugs.
This commit is contained in:
parent
342ff4d8f0
commit
808c6d5033
|
@ -18,7 +18,7 @@
|
|||
The ctlseqs library provides low-level C API for manipulating terminal
|
||||
emulators with control sequences.
|
||||
|
||||
This library is free software. you can redistribute it and/or modify it
|
||||
Ctlseqs is free software. you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation, either version 3 of the License, or (at your
|
||||
option) any later version.
|
||||
|
|
|
@ -41,8 +41,6 @@ AC_TYPE_SIZE_T
|
|||
AC_TYPE_SSIZE_T
|
||||
|
||||
# Checks for library functions.
|
||||
AC_FUNC_MALLOC
|
||||
AC_FUNC_REALLOC
|
||||
AC_CHECK_FUNCS([dprintf memset strtoul])
|
||||
|
||||
AC_CONFIG_FILES([Makefile man/Makefile src/Makefile tests/Makefile examples/Makefile])
|
||||
|
|
|
@ -51,6 +51,7 @@ A control sequence is successfully read, but fails to match any pattern in
|
|||
.TP
|
||||
.B CTLSEQS_PARTIAL
|
||||
Data is read successfully and can be recognized as part of a control sequence, but is not yet terminated.
|
||||
Partial sequence is not consumed from the read buffer.
|
||||
.TP
|
||||
.B CTLSEQS_NOSEQ
|
||||
Data is read successfully, but cannot be recognized as a valid control sequence.
|
||||
|
@ -60,6 +61,11 @@ The specified
|
|||
.I timeout
|
||||
has expired, and no data is read.
|
||||
.TP
|
||||
.B CTLSEQS_NOMEM
|
||||
Like
|
||||
.BR CTLSEQS_PARTIAL ,
|
||||
but the internal read buffer is full, and no data can be further read.
|
||||
.TP
|
||||
.B CTLSEQS_EOF
|
||||
End-of-file is encountered, and no data is read.
|
||||
.TP
|
||||
|
|
|
@ -162,8 +162,8 @@ ctlseqs_poll(struct pollfd *pollfd, int timeout)
|
|||
CTLSEQS_HOT static inline int
|
||||
ctlseqs_do_read(struct ctlseqs_reader *reader)
|
||||
{
|
||||
char *buf = reader->rbuf + reader->buf_start + reader->last_idx;
|
||||
ssize_t nbytes = read(reader->pollfd.fd, buf, reader->readlen - reader->buf_start);
|
||||
size_t offset = reader->buf_start + reader->last_idx;
|
||||
ssize_t nbytes = read(reader->pollfd.fd, reader->rbuf + offset, reader->readlen - offset);
|
||||
if (CTLSEQS_UNLIKELY(nbytes == -1)) {
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||
return CTLSEQS_TIMEOUT;
|
||||
|
@ -331,6 +331,7 @@ ctlseqs_match(struct ctlseqs_reader *reader, struct ctlseqs_matcher const *match
|
|||
for (idx = reader->last_idx; idx < len; ++idx) {
|
||||
state = ctlseqs_state_transition(state, buf[idx]);
|
||||
if (state == ctlseqs_state_err) {
|
||||
// Anything before next ESC is definitely not a control sequence.
|
||||
for (; idx < len; ++idx) {
|
||||
if (buf[idx] == 0x1b) {
|
||||
break;
|
||||
|
@ -341,24 +342,39 @@ ctlseqs_match(struct ctlseqs_reader *reader, struct ctlseqs_matcher const *match
|
|||
}
|
||||
if (state == ctlseqs_state_done) {
|
||||
retval = ctlseqs_match_pattern(reader, matcher);
|
||||
++idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
reader->state = state >= ctlseqs_state_done ? ctlseqs_state_none : state;
|
||||
if (retval == CTLSEQS_NOMATCH || retval == CTLSEQS_PARTIAL || retval == CTLSEQS_NOSEQ) {
|
||||
if (retval < 0) {
|
||||
reader->buffer[0].num = idx;
|
||||
reader->buffer[1].str = buf;
|
||||
}
|
||||
if (retval == CTLSEQS_PARTIAL) {
|
||||
reader->last_idx = idx;
|
||||
if (CTLSEQS_UNLIKELY(reader->buf_start + idx == reader->readlen)) {
|
||||
// Buffer is full but a match is still pending.
|
||||
// This may happen when the reader's maxlen option is not large enough to hold a sequence,
|
||||
// or when the the sequences are produced faster than consumed.
|
||||
if (reader->buf_start > reader->readlen / 2) {
|
||||
memcpy(reader->rbuf, reader->rbuf + reader->buf_start, idx);
|
||||
reader->buf_start = 0;
|
||||
reader->buf_end = idx;
|
||||
} else {
|
||||
// We could memmove() here, but having a buffer no larger than twice the size of a sequence
|
||||
// is hardly what a normal program would desire.
|
||||
retval = CTLSEQS_NOMEM;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
reader->buf_start += idx;
|
||||
reader->last_idx = 0;
|
||||
if (reader->buf_start == reader->buf_end) {
|
||||
reader->buf_start = 0;
|
||||
reader->buf_end = 0;
|
||||
}
|
||||
}
|
||||
if (reader->buf_start == reader->buf_end) {
|
||||
reader->buf_start = 0;
|
||||
reader->buf_end = 0;
|
||||
}
|
||||
reader->state = state >= ctlseqs_state_done ? ctlseqs_state_none : state;
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -459,14 +475,10 @@ ctlseqs_reader_setopt(struct ctlseqs_reader *reader, struct ctlseqs_reader_opts
|
|||
size_t readlen = options->maxlen;
|
||||
if (reader->readlen != readlen) {
|
||||
char *rbuf;
|
||||
if (reader->rbuf == NULL) {
|
||||
rbuf = malloc(readlen);
|
||||
} else {
|
||||
if (readlen < reader->buf_end) {
|
||||
return CTLSEQS_ERROR;
|
||||
}
|
||||
rbuf = realloc(reader->rbuf, readlen);
|
||||
if (readlen < reader->buf_end) {
|
||||
return CTLSEQS_ERROR;
|
||||
}
|
||||
rbuf = realloc(reader->rbuf, readlen);
|
||||
if (rbuf == NULL) {
|
||||
return CTLSEQS_NOMEM;
|
||||
}
|
||||
|
|
|
@ -381,7 +381,7 @@ main(int argc, char **argv)
|
|||
printf("TIMEOUT\n");
|
||||
break;
|
||||
case CTLSEQS_INTR:
|
||||
printf("INTERRUPTED\n");
|
||||
printf("INTR\n");
|
||||
break;
|
||||
case CTLSEQS_EOF:
|
||||
printf("EOF\n");
|
||||
|
|
Loading…
Reference in New Issue