Drop strbuf's 'eof' marker, and make read_line a first class citizen.
authorPierre Habouzit <madcoder@debian.org>
Mon, 17 Sep 2007 09:19:04 +0000 (11:19 +0200)
committerJunio C Hamano <gitster@pobox.com>
Tue, 18 Sep 2007 07:55:10 +0000 (00:55 -0700)
read_line is now strbuf_getline, and is a first class citizen, it returns 0
when reading a line worked, EOF else.

The ->eof marker was used non-locally by fast-import.c, mimic the same
behaviour using a static int in "read_next_command", that now returns -1 on
EOF, and avoids to call strbuf_getline when it's in EOF state.

Also no longer automagically strbuf_release the buffer, it's counter
intuitive and breaks fast-import in a very subtle way.

Note: being at EOF implies that command_buf.len == 0.

Signed-off-by: Pierre Habouzit <madcoder@debian.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin-checkout-index.c
builtin-update-index.c
fast-import.c
fetch.c
mktree.c
strbuf.c
strbuf.h

index 85e8efe..a18ecc4 100644 (file)
@@ -277,9 +277,7 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix)
                while (1) {
                        char *path_name;
                        const char *p;
-
-                       read_line(&buf, stdin, line_termination);
-                       if (buf.eof)
+                       if (strbuf_getline(&buf, stdin, line_termination) == EOF)
                                break;
                        if (line_termination && buf.buf[0] == '"')
                                path_name = unquote_c_style(buf.buf, NULL);
@@ -292,6 +290,7 @@ int cmd_checkout_index(int argc, const char **argv, const char *prefix)
                        if (path_name != buf.buf)
                                free(path_name);
                }
+               strbuf_release(&buf);
        }
 
        if (all)
index 1091f1b..45e33f5 100644 (file)
@@ -327,8 +327,7 @@ static void read_index_info(int line_termination)
                 * This format is to put higher order stages into the
                 * index file and matches git-ls-files --stage output.
                 */
-               read_line(&buf, stdin, line_termination);
-               if (buf.eof)
+               if (strbuf_getline(&buf, stdin, line_termination) == EOF)
                        break;
 
                errno = 0;
@@ -391,6 +390,7 @@ static void read_index_info(int line_termination)
        bad_line:
                die("malformed index info %s", buf.buf);
        }
+       strbuf_release(&buf);
 }
 
 static const char update_index_usage[] =
@@ -719,8 +719,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
                while (1) {
                        char *path_name;
                        const char *p;
-                       read_line(&buf, stdin, line_termination);
-                       if (buf.eof)
+                       if (strbuf_getline(&buf, stdin, line_termination) == EOF)
                                break;
                        if (line_termination && buf.buf[0] == '"')
                                path_name = unquote_c_style(buf.buf, NULL);
@@ -735,6 +734,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
                        if (path_name != buf.buf)
                                free(path_name);
                }
+               strbuf_release(&buf);
        }
 
  finish:
index 1866d34..da04566 100644 (file)
@@ -1584,20 +1584,25 @@ static void dump_marks(void)
                        mark_file, strerror(errno));
 }
 
-static void read_next_command(void)
+static int read_next_command(void)
 {
+       static int stdin_eof = 0;
+
+       if (stdin_eof) {
+               unread_command_buf = 0;
+               return EOF;
+       }
+
        do {
                if (unread_command_buf) {
                        unread_command_buf = 0;
-                       if (command_buf.eof)
-                               return;
                } else {
                        struct recent_command *rc;
 
                        strbuf_detach(&command_buf);
-                       read_line(&command_buf, stdin, '\n');
-                       if (command_buf.eof)
-                               return;
+                       stdin_eof = strbuf_getline(&command_buf, stdin, '\n');
+                       if (stdin_eof)
+                               return EOF;
 
                        rc = rc_free;
                        if (rc)
@@ -1616,6 +1621,8 @@ static void read_next_command(void)
                        cmd_tail = rc;
                }
        } while (command_buf.buf[0] == '#');
+
+       return 0;
 }
 
 static void skip_optional_lf(void)
@@ -1648,8 +1655,7 @@ static void *cmd_data (size_t *size)
                size_t term_len = command_buf.len - 5 - 2;
 
                for (;;) {
-                       read_line(&command_buf, stdin, '\n');
-                       if (command_buf.eof)
+                       if (strbuf_getline(&command_buf, stdin, '\n') == EOF)
                                die("EOF in data (terminator '%s' not found)", term);
                        if (term_len == command_buf.len
                                && !strcmp(term, command_buf.buf))
@@ -2095,7 +2101,7 @@ static void cmd_new_commit(void)
        }
 
        /* file_change* */
-       while (!command_buf.eof && command_buf.len > 0) {
+       while (command_buf.len > 0) {
                if (!prefixcmp(command_buf.buf, "M "))
                        file_change_m(b);
                else if (!prefixcmp(command_buf.buf, "D "))
@@ -2110,7 +2116,8 @@ static void cmd_new_commit(void)
                        unread_command_buf = 1;
                        break;
                }
-               read_next_command();
+               if (read_next_command() == EOF)
+                       break;
        }
 
        /* build the tree and the commit */
@@ -2375,11 +2382,8 @@ int main(int argc, const char **argv)
        prepare_packed_git();
        start_packfile();
        set_die_routine(die_nicely);
-       for (;;) {
-               read_next_command();
-               if (command_buf.eof)
-                       break;
-               else if (!strcmp("blob", command_buf.buf))
+       while (read_next_command() != EOF) {
+               if (!strcmp("blob", command_buf.buf))
                        cmd_new_blob();
                else if (!prefixcmp(command_buf.buf, "commit "))
                        cmd_new_commit();
diff --git a/fetch.c b/fetch.c
index c256e6f..b1c1f07 100644 (file)
--- a/fetch.c
+++ b/fetch.c
@@ -222,8 +222,7 @@ int pull_targets_stdin(char ***target, const char ***write_ref)
                char *rf_one = NULL;
                char *tg_one;
 
-               read_line(&buf, stdin, '\n');
-               if (buf.eof)
+               if (strbuf_getline(&buf, stdin, '\n') == EOF)
                        break;
                tg_one = buf.buf;
                rf_one = strchr(tg_one, '\t');
@@ -239,6 +238,7 @@ int pull_targets_stdin(char ***target, const char ***write_ref)
                (*write_ref)[targets] = rf_one ? xstrdup(rf_one) : NULL;
                targets++;
        }
+       strbuf_release(&buf);
        return targets;
 }
 
index 5dab4bd..9c137de 100644 (file)
--- a/mktree.c
+++ b/mktree.c
@@ -88,8 +88,7 @@ int main(int ac, char **av)
                enum object_type type;
                char *path;
 
-               read_line(&sb, stdin, line_termination);
-               if (sb.eof)
+               if (strbuf_getline(&sb, stdin, line_termination) == EOF)
                        break;
                ptr = sb.buf;
                /* Input is non-recursive ls-tree output format
@@ -121,6 +120,7 @@ int main(int ac, char **av)
                if (path != ntr)
                        free(path);
        }
+       strbuf_release(&sb);
        write_tree(sha1);
        puts(sha1_to_hex(sha1));
        exit(0);
index c5f9e2a..59383ac 100644 (file)
--- a/strbuf.c
+++ b/strbuf.c
@@ -17,7 +17,6 @@ void strbuf_reset(struct strbuf *sb)
 {
        if (sb->len)
                strbuf_setlen(sb, 0);
-       sb->eof = 0;
 }
 
 char *strbuf_detach(struct strbuf *sb)
@@ -145,14 +144,13 @@ ssize_t strbuf_read(struct strbuf *sb, int fd, size_t hint)
        return sb->len - oldlen;
 }
 
-void read_line(struct strbuf *sb, FILE *fp, int term)
+int strbuf_getline(struct strbuf *sb, FILE *fp, int term)
 {
        int ch;
-       if (feof(fp)) {
-               strbuf_release(sb);
-               sb->eof = 1;
-               return;
-       }
+
+       strbuf_grow(sb, 0);
+       if (feof(fp))
+               return EOF;
 
        strbuf_reset(sb);
        while ((ch = fgetc(fp)) != EOF) {
@@ -161,11 +159,9 @@ void read_line(struct strbuf *sb, FILE *fp, int term)
                strbuf_grow(sb, 1);
                sb->buf[sb->len++] = ch;
        }
-       if (ch == EOF && sb->len == 0) {
-               strbuf_release(sb);
-               sb->eof = 1;
-       }
+       if (ch == EOF && sb->len == 0)
+               return EOF;
 
-       strbuf_grow(sb, 1);
        sb->buf[sb->len] = '\0';
+       return 0;
 }
index f163c63..b2cbd97 100644 (file)
--- a/strbuf.h
+++ b/strbuf.h
 struct strbuf {
        size_t alloc;
        size_t len;
-       int eof;
        char *buf;
 };
 
-#define STRBUF_INIT  { 0, 0, 0, NULL }
+#define STRBUF_INIT  { 0, 0, NULL }
 
 /*----- strbuf life cycle -----*/
 extern void strbuf_init(struct strbuf *, size_t);
@@ -101,6 +100,6 @@ extern size_t strbuf_fread(struct strbuf *, size_t, FILE *);
 /* XXX: if read fails, any partial read is undone */
 extern ssize_t strbuf_read(struct strbuf *, int fd, size_t hint);
 
-extern void read_line(struct strbuf *, FILE *, int);
+extern int strbuf_getline(struct strbuf *, FILE *, int);
 
 #endif /* STRBUF_H */