From: Andre Noll Date: Mon, 25 Mar 2013 18:02:54 +0000 (+0000) Subject: string: Add discard feature for for_each_line(). X-Git-Tag: v0.4.13~33^2~1 X-Git-Url: http://git.tue.mpg.de/?a=commitdiff_plain;h=bcc0838f240081150a5d11f176326efe95a7d382;p=paraslash.git string: Add discard feature for for_each_line(). This adds the new FELF_DISCARD_FIRST flag which instructs for_each_line() to discard everything up to the next newline. The new feature is only used by para_gui. When para_gui detects a partial overlong input line, it ignores this data and passes the FELF_DISCARD_FIRST flag in subsequent calls to for_each_line(). Hence output continues at the next line. --- diff --git a/gui.c b/gui.c index 7bb74e6f..85d77c9e 100644 --- a/gui.c +++ b/gui.c @@ -982,6 +982,7 @@ static int do_select(int mode) char command_buf[2][COMMAND_BUF_SIZE] = {"", ""}; int cbo[2] = {0, 0}; /* command buf offsets */ struct timeval tv; + unsigned flags[2] = {0, 0}; /* for for_each_line() */ repeat: tv.tv_sec = conf.timeout_arg / 1000; @@ -1019,21 +1020,25 @@ repeat: COMMAND_BUF_SIZE - 1 - cbo[i], &rfds, &sz); cbo[i] += sz; sz = cbo[i]; - cbo[i] = for_each_line(0, command_buf[i], cbo[i], + cbo[i] = for_each_line(flags[i], command_buf[i], cbo[i], add_output_line, &i); - if (sz != cbo[i]) + if (sz != cbo[i]) { /* at least one line found */ wrefresh(bot.win); + flags[i] = 0; + } if (ret < 0) { PARA_NOTICE_LOG("closing command fd %d: %s", i, para_strerror(-ret)); close(command_fds[i]); command_fds[i] = -1; + flags[i] = 0; if (command_fds[!i] < 0) /* both fds closed */ return 0; } if (cbo[i] == COMMAND_BUF_SIZE - 1) { PARA_NOTICE_LOG("discarding overlong line"); cbo[i] = 0; + flags[i] = FELF_DISCARD_FIRST; } } } diff --git a/string.c b/string.c index c0a1951d..ba744bff 100644 --- a/string.c +++ b/string.c @@ -399,20 +399,21 @@ int for_each_line(unsigned flags, char *buf, size_t size, } else end = next_cr; num_lines++; - if (flags & FELF_READ_ONLY) { - size_t s = end - start; - char *b = para_malloc(s + 1); - memcpy(b, start, s); - b[s] = '\0'; -// PARA_NOTICE_LOG("b: %s, start: %s\n", b, start); - ret = line_handler(b, private_data); - free(b); - } else { - *end = '\0'; - ret = line_handler(start, private_data); + if (!(flags & FELF_DISCARD_FIRST) || start != buf) { + if (flags & FELF_READ_ONLY) { + size_t s = end - start; + char *b = para_malloc(s + 1); + memcpy(b, start, s); + b[s] = '\0'; + ret = line_handler(b, private_data); + free(b); + } else { + *end = '\0'; + ret = line_handler(start, private_data); + } + if (ret < 0) + return ret; } - if (ret < 0) - return ret; start = ++end; } i = buf + size - start; diff --git a/string.h b/string.h index 6d099074..230f654b 100644 --- a/string.h +++ b/string.h @@ -42,6 +42,8 @@ struct para_buffer { enum for_each_line_flags { /** Activate read-only mode. */ FELF_READ_ONLY = 1 << 0, + /** Don't call line handler for the first input line. */ + FELF_DISCARD_FIRST = 1 << 1, }; /** Used for \ref for_each_line(). */