git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Pierre Habouzit <madcoder@debian.org>
To: Junio C Hamano <gitster@pobox.com>
Cc: git@vger.kernel.org
Subject: [PATCH 1/3] Drop strbuf's 'eof' marker, and make read_line a first class citizen.
Date: Mon, 17 Sep 2007 11:19:04 +0200	[thread overview]
Message-ID: <20070917125257.1BF16344A4A@madism.org> (raw)
In-Reply-To: <20070917125211.GA18176@artemis.corp>

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>
---
 builtin-checkout-index.c |    5 ++---
 builtin-update-index.c   |    8 ++++----
 fast-import.c            |   34 +++++++++++++++++++---------------
 fetch.c                  |    4 ++--
 mktree.c                 |    4 ++--
 strbuf.c                 |   20 ++++++++------------
 strbuf.h                 |    5 ++---
 7 files changed, 39 insertions(+), 41 deletions(-)

diff --git a/builtin-checkout-index.c b/builtin-checkout-index.c
index 85e8efe..a18ecc4 100644
--- a/builtin-checkout-index.c
+++ b/builtin-checkout-index.c
@@ -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)
diff --git a/builtin-update-index.c b/builtin-update-index.c
index 0b60513..acd5ab5 100644
--- a/builtin-update-index.c
+++ b/builtin-update-index.c
@@ -320,8 +320,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;
@@ -383,6 +382,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[] =
@@ -710,8 +710,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);
@@ -726,6 +725,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:
diff --git a/fast-import.c b/fast-import.c
index 1866d34..da04566 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -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
--- 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;
 }
 
diff --git a/mktree.c b/mktree.c
index 5dab4bd..9c137de 100644
--- 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);
diff --git a/strbuf.c b/strbuf.c
index c5f9e2a..59383ac 100644
--- 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;
 }
diff --git a/strbuf.h b/strbuf.h
index f163c63..b2cbd97 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -44,11 +44,10 @@
 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 */
-- 
1.5.3.1

  reply	other threads:[~2007-09-17 12:53 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-09-17 12:52 [PATCH 0/3] the return of the strbuf Pierre Habouzit
2007-09-17  9:19 ` Pierre Habouzit [this message]
2007-09-17 11:48 ` [PATCH 2/3] fast-import was using dbuf's, replace them with strbuf's Pierre Habouzit
2007-09-17 12:00 ` [PATCH 3/3] fast-import optimization: Pierre Habouzit
2007-09-17 13:35 ` [PATCH 0/3] the return of the strbuf Pierre Habouzit
2007-09-18  3:57   ` Shawn O. Pearce
2007-09-20 11:49     ` Johannes Schindelin
2007-09-20 14:19       ` Shawn O. Pearce
2007-09-20 21:41       ` Junio C Hamano
2007-09-20 21:52         ` Johannes Schindelin
2007-09-18  7:56 ` Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20070917125257.1BF16344A4A@madism.org \
    --to=madcoder@debian.org \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).