sob

Simple output bar
git clone https://git.sinitax.com/codemadness/sob
Log | Files | Refs | README | LICENSE | Upstream | sfeed.txt

commit 94943b8e5e88cd90374abc46d954657c6fc63f51
parent 0d01477d561d460a40b68ec469b23d9edb2e88a0
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date:   Fri, 10 Oct 2014 21:54:57 +0000

make input handling more flexible

- improve non-blocked reads.
- allow to pipe multiple lines using callbacks (same as handleinput for
  cb_* callbacks).
- change -l to -i, because input can now be more than just text.

Diffstat:
Msob.c | 114++++++++++++++++++++++++++++++++++++++++---------------------------------------
1 file changed, 58 insertions(+), 56 deletions(-)

diff --git a/sob.c b/sob.c @@ -30,6 +30,9 @@ struct line { size_t collen; /* total length (in columns) */ }; +static void cb_pipe_insert(const char *, size_t); +static void cb_pipe_replaceword(const char *, size_t); + static void line_clear(void); static void line_copywordcursor(char *, size_t); static void line_cursor_begin(void); @@ -56,10 +59,10 @@ static void line_out(void); static void line_prompt(void); static int line_promptlen(void); static int line_pipeto(char **); -static void line_set(const char *); static int line_wordpipeto(char **); -static int pipe_readline(int, int, char *, char *, size_t); -static int pipe_cmd(char *[], char *, char *, size_t); + +static int pipe_readline(int, int, char *, void (*)(const char *, size_t)); +static int pipe_cmd(char *[], char *, void (*)(const char *, size_t)); static void cleanup(void); static void gettermsize(void); @@ -211,13 +214,6 @@ line_inserttext(const char *s) line.collen = colw(line.line, line.bytesiz); } -static void -line_set(const char *s) -{ - memset(&line, 0, sizeof(line)); - line_inserttext(s); -} - /* like mksh, toggle counting of escape codes in prompt with "\x01" */ static int line_promptlen(void) @@ -537,10 +533,10 @@ line_copywordcursor(char *buf, size_t bufsiz) } static int -pipe_readline(int fd_in, int fd_out, char *writestr, char *outbuf, - size_t outbufsiz) +pipe_readline(int fd_in, int fd_out, char *writestr, + void (*f)(const char *, size_t)) { - char buf[PIPE_BUF], *p; + char buf[PIPE_BUF]; struct timeval tv; fd_set fdr, fdw; int r, w, maxfd, status = -1, haswritten = 0; @@ -567,17 +563,21 @@ pipe_readline(int fd_in, int fd_out, char *writestr, char *outbuf, if(haswritten) { if(FD_ISSET(fd_in, &fdr)) { - /* read until newline */ - if((r = read(fd_in, buf, sizeof(buf))) == -1) - goto fini; - buf[r] = '\0'; - if(outbuf) { - if((p = strpbrk(buf, "\r\n"))) - *p = '\0'; - strlcpy(outbuf, buf, outbufsiz); + while(1) { + if((r = read(fd_in, buf, sizeof(buf))) == -1) { + if(errno == EINTR) + continue; + goto fini; + } else { + buf[r] = '\0'; + if(f) + f(buf, r); + if(!r) { + status = 0; + goto fini; + } + } } - status = 0; - goto fini; } } else { if(FD_ISSET(fd_out, &fdw)) { @@ -599,7 +599,7 @@ fini: } static int -pipe_cmd(char *cmd[], char *writestr, char *outbuf, size_t outbufsiz) +pipe_cmd(char *cmd[], char *writestr, void (*f)(const char *, size_t)) { struct sigaction sa; pid_t pid; @@ -640,48 +640,46 @@ pipe_cmd(char *cmd[], char *writestr, char *outbuf, size_t outbufsiz) sa.sa_handler = SIG_IGN; sigaction(SIGPIPE, &sa, NULL); - if(pipe_readline(cp[0], pc[1], writestr, outbuf, outbufsiz) == -1) + if(pipe_readline(cp[0], pc[1], writestr, f) == -1) return -1; } return 0; } +static void +cb_pipe_insert(const char *buf, size_t len) +{ + if(!len) + return; + memset(&line, 0, sizeof(line)); + handleinput((unsigned char *)buf, len); +} + +static void +cb_pipe_replaceword(const char *buf, size_t len) +{ + if(!len) + return; + line_delwordcursor(); + handleinput((unsigned char *)buf, len); +} + static int line_pipeto(char **cmd) { - char buf[BUFSIZ]; - - if(pipe_cmd(cmd, line.line, buf, sizeof(buf)) == -1) - return -1; - if(buf[0] == '\0') - return -1; - line_set(buf); - line_cursor_end(); - line_draw(); - return 0; + return pipe_cmd(cmd, line.line, cb_pipe_insert); } /* pipe word under cursor and replace it */ static int line_wordpipeto(char **cmd) { - char wordbuf[BUFSIZ], outbuf[BUFSIZ]; + char wordbuf[BUFSIZ]; - outbuf[0] = '\0'; wordbuf[0] = '\0'; line_copywordcursor(wordbuf, sizeof(wordbuf)); - if(pipe_cmd((char**)cmd, wordbuf, outbuf, - sizeof(outbuf)) == -1) - return -1; - if(outbuf[0] == '\0') - return -1; - - line_delwordcursor(); - line_inserttext(outbuf); - line_draw(); - - return 0; + return pipe_cmd((char**)cmd, wordbuf, cb_pipe_replaceword); } static void @@ -736,7 +734,7 @@ gettermsize(void) static void resize(void) { - pipe_cmd((char **)resizecmd, line.line, NULL, 0); + pipe_cmd((char **)resizecmd, line.line, NULL); } static void @@ -795,9 +793,10 @@ run(void) int r, status = -1; unsigned char buf[BUFSIZ]; - line_draw(); - - fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK); + if(isrunning) { + line_draw(); + fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK); + } while(isrunning) { FD_ZERO(&fdr); FD_SET(STDIN_FILENO, &fdr); @@ -832,16 +831,18 @@ fini: static void usage(void) { - fprintf(stderr, "usage: %s [-l line] [-p prompt]\n", argv0); + fprintf(stderr, "usage: %s [-i input] [-p prompt]\n", argv0); exit(EXIT_FAILURE); } int main(int argc, char **argv) { + char *input = NULL; + ARGBEGIN { - case 'l': - line_set(EARGF(usage())); + case 'i': + input = EARGF(usage()); break; case 'p': prompt = EARGF(usage()); @@ -852,9 +853,10 @@ main(int argc, char **argv) lineoutfp = stdout; outfp = stderr; - setlocale(LC_ALL, ""); setup(); + if(input) + handleinput((unsigned char *)input, strlen(input)); run(); cleanup();