Update documentation. Fix bugs.

This commit is contained in:
CismonX 2020-12-09 17:48:19 +08:00
parent 342ff4d8f0
commit 808c6d5033
Signed by: cismonx
GPG Key ID: 3094873E29A482FB
5 changed files with 35 additions and 19 deletions

View File

@ -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.

View File

@ -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])

View File

@ -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

View File

@ -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;
}

View File

@ -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");