string: Add discard feature for for_each_line().
authorAndre Noll <maan@systemlinux.org>
Mon, 25 Mar 2013 18:02:54 +0000 (18:02 +0000)
committerAndre Noll <maan@systemlinux.org>
Thu, 2 May 2013 17:56:09 +0000 (19:56 +0200)
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.

gui.c
string.c
string.h

diff --git a/gui.c b/gui.c
index 7bb74e6..85d77c9 100644 (file)
--- 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;
        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;
 
 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];
                                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);
                                add_output_line, &i);
-                       if (sz != cbo[i])
+                       if (sz != cbo[i]) { /* at least one line found */
                                wrefresh(bot.win);
                                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;
                        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;
                                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;
                        }
                }
        }
                        }
                }
        }
index c0a1951..ba744bf 100644 (file)
--- 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++;
                } 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;
                start = ++end;
        }
        i = buf + size - start;
index 6d09907..230f654 100644 (file)
--- 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,
 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(). */
 };
 
 /** Used for \ref for_each_line(). */