git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 5/7] Further strbuf re-engineering.

From
Pierre Habouzit <madcoder@debian.org>
Date
Sep 6, 2007, 11:20 UTC
Message-ID
<11890776112309-git-send-email-madcoder@debian.org>
In-Reply-To
<11890776111670-git-send-email-madcoder@debian.org>
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
---
 builtin-apply.c       |   30 +++++++-----------------
 builtin-blame.c       |   35 +++++++++------------------
 builtin-commit-tree.c |   60 +++++++++++-------------------------------------
 diff.c                |   27 +++++++--------------
 4 files changed, 44 insertions(+), 108 deletions(-)
diff --git a/builtin-apply.c b/builtin-apply.c
index 25b1447..d70c6cf 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -12,6 +12,7 @@
 #include "blob.h"
 #include "delta.h"
 #include "builtin.h"
+#include "strbuf.h"
 
 /*
  *  --check turns on checking that the working tree matches the
@@ -181,34 +182,21 @@ static void say_patch_name(FILE *output, const char *pre, struct patch *patch, c
 
 static void *read_patch_file(int fd, unsigned long *sizep)
 {
-	unsigned long size = 0, alloc = CHUNKSIZE;
-	void *buffer = xmalloc(alloc);
+	struct strbuf buf;
 
-	for (;;) {
-		ssize_t nr = alloc - size;
-		if (nr < 1024) {
-			alloc += CHUNKSIZE;
-			buffer = xrealloc(buffer, alloc);
-			nr = alloc - size;
-		}
-		nr = xread(fd, (char *) buffer + size, nr);
-		if (!nr)
-			break;
-		if (nr < 0)
-			die("git-apply: read returned %s", strerror(errno));
-		size += nr;
-	}
-	*sizep = size;
+        strbuf_init(&buf);
+	if (strbuf_read(&buf, fd) < 0)
+		die("git-apply: read returned %s", strerror(errno));
+	*sizep = buf.len;
 
 	/*
 	 * Make sure that we have some slop in the buffer
 	 * so that we can do speculative "memcmp" etc, and
 	 * see to it that it is NUL-filled.
 	 */
-	if (alloc < size + SLOP)
-		buffer = xrealloc(buffer, size + SLOP);
-	memset((char *) buffer + size, 0, SLOP);
-	return buffer;
+	strbuf_grow(&buf, SLOP);
+	memset(buf.buf + buf.len, 0, SLOP);
+	return strbuf_detach(&buf);
 }
 
 static unsigned long linelen(const char *buffer, unsigned long size)
diff --git a/builtin-blame.c b/builtin-blame.c
index dc88a95..1b1e6da 100644
--- a/builtin-blame.c
+++ b/builtin-blame.c
@@ -18,6 +18,7 @@
 #include "cache-tree.h"
 #include "path-list.h"
 #include "mailmap.h"
+#include "strbuf.h"
 
 static char blame_usage[] =
 "git-blame [-c] [-b] [-l] [--root] [-t] [-f] [-n] [-s] [-p] [-w] [-L n,m] [-S <revs-file>] [-M] [-C] [-C] [--contents <filename>] [--incremental] [commit] [--] file\n"
@@ -2001,11 +2002,10 @@ static struct commit *fake_working_tree_commit(const char *path, const char *con
 	struct commit *commit;
 	struct origin *origin;
 	unsigned char head_sha1[20];
-	char *buf;
+	struct strbuf buf;
 	const char *ident;
 	int fd;
 	time_t now;
-	unsigned long fin_size;
 	int size, len;
 	struct cache_entry *ce;
 	unsigned mode;
@@ -2023,9 +2023,11 @@ static struct commit *fake_working_tree_commit(const char *path, const char *con
 
 	origin = make_origin(commit, path);
 
+	strbuf_init(&buf);
 	if (!contents_from || strcmp("-", contents_from)) {
 		struct stat st;
 		const char *read_from;
+		unsigned long fin_size;
 
 		if (contents_from) {
 			if (stat(contents_from, &st) < 0)
@@ -2038,19 +2040,19 @@ static struct commit *fake_working_tree_commit(const char *path, const char *con
 			read_from = path;
 		}
 		fin_size = xsize_t(st.st_size);
-		buf = xmalloc(fin_size+1);
 		mode = canon_mode(st.st_mode);
 		switch (st.st_mode & S_IFMT) {
 		case S_IFREG:
 			fd = open(read_from, O_RDONLY);
 			if (fd < 0)
 				die("cannot open %s", read_from);
-			if (read_in_full(fd, buf, fin_size) != fin_size)
+			if (strbuf_read(&buf, fd) != xsize_t(st.st_size))
 				die("cannot read %s", read_from);
 			break;
 		case S_IFLNK:
-			if (readlink(read_from, buf, fin_size+1) != fin_size)
+			if (readlink(read_from, buf.buf, buf.alloc) != fin_size)
 				die("cannot readlink %s", read_from);
+			buf.len = fin_size;
 			break;
 		default:
 			die("unsupported file type %s", read_from);
@@ -2059,26 +2061,13 @@ static struct commit *fake_working_tree_commit(const char *path, const char *con
 	else {
 		/* Reading from stdin */
 		contents_from = "standard input";
-		buf = NULL;
-		fin_size = 0;
 		mode = 0;
-		while (1) {
-			ssize_t cnt = 8192;
-			buf = xrealloc(buf, fin_size + cnt);
-			cnt = xread(0, buf + fin_size, cnt);
-			if (cnt < 0)
-				die("read error %s from stdin",
-				    strerror(errno));
-			if (!cnt)
-				break;
-			fin_size += cnt;
-		}
-		buf = xrealloc(buf, fin_size + 1);
+		if (strbuf_read(&buf, 0) < 0)
+			die("read error %s from stdin", strerror(errno));
 	}
-	buf[fin_size] = 0;
-	origin->file.ptr = buf;
-	origin->file.size = fin_size;
-	pretend_sha1_file(buf, fin_size, OBJ_BLOB, origin->blob_sha1);
+	origin->file.ptr = buf.buf;
+	origin->file.size = buf.len;
+	pretend_sha1_file(buf.buf, buf.len, OBJ_BLOB, origin->blob_sha1);
 	commit->util = origin;
 
 	/*
diff --git a/builtin-commit-tree.c b/builtin-commit-tree.c
index ccbcbe3..bc9502c 100644
--- a/builtin-commit-tree.c
+++ b/builtin-commit-tree.c
@@ -8,42 +8,13 @@
 #include "tree.h"
 #include "builtin.h"
 #include "utf8.h"
+#include "strbuf.h"
 
 #define BLOCKING (1ul << 14)
 
 /*
  * FIXME! Share the code with "write-tree.c"
  */
-static void init_buffer(char **bufp, unsigned int *sizep)
-{
-	*bufp = xmalloc(BLOCKING);
-	*sizep = 0;
-}
-
-static void add_buffer(char **bufp, unsigned int *sizep, const char *fmt, ...)
-{
-	char one_line[2048];
-	va_list args;
-	int len;
-	unsigned long alloc, size, newsize;
-	char *buf;
-
-	va_start(args, fmt);
-	len = vsnprintf(one_line, sizeof(one_line), fmt, args);
-	va_end(args);
-	size = *sizep;
-	newsize = size + len + 1;
-	alloc = (size + 32767) & ~32767;
-	buf = *bufp;
-	if (newsize > alloc) {
-		alloc = (newsize + 32767) & ~32767;
-		buf = xrealloc(buf, alloc);
-		*bufp = buf;
-	}
-	*sizep = newsize - 1;
-	memcpy(buf + size, one_line, len);
-}
-
 static void check_valid(unsigned char *sha1, enum object_type expect)
 {
 	enum object_type type = sha1_object_info(sha1, NULL);
@@ -87,9 +58,7 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
 	int parents = 0;
 	unsigned char tree_sha1[20];
 	unsigned char commit_sha1[20];
-	char comment[1000];
-	char *buffer;
-	unsigned int size;
+	struct strbuf buffer;
 	int encoding_is_utf8;
 
 	git_config(git_default_config);
@@ -118,8 +87,9 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
 	/* Not having i18n.commitencoding is the same as having utf-8 */
 	encoding_is_utf8 = is_encoding_utf8(git_commit_encoding);
 
-	init_buffer(&buffer, &size);
-	add_buffer(&buffer, &size, "tree %s\n", sha1_to_hex(tree_sha1));
+	strbuf_init(&buffer);
+	strbuf_grow(&buffer, 8192); /* should avoid reallocs for the headers */
+	strbuf_addf(&buffer, "tree %s\n", sha1_to_hex(tree_sha1));
 
 	/*
 	 * NOTE! This ordering means that the same exact tree merged with a
@@ -127,26 +97,24 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
 	 * if everything else stays the same.
 	 */
 	for (i = 0; i < parents; i++)
-		add_buffer(&buffer, &size, "parent %s\n", sha1_to_hex(parent_sha1[i]));
+		strbuf_addf(&buffer, "parent %s\n", sha1_to_hex(parent_sha1[i]));
 
 	/* Person/date information */
-	add_buffer(&buffer, &size, "author %s\n", git_author_info(1));
-	add_buffer(&buffer, &size, "committer %s\n", git_committer_info(1));
+	strbuf_addf(&buffer, "author %s\n", git_author_info(1));
+	strbuf_addf(&buffer, "committer %s\n", git_committer_info(1));
 	if (!encoding_is_utf8)
-		add_buffer(&buffer, &size,
-				"encoding %s\n", git_commit_encoding);
-	add_buffer(&buffer, &size, "\n");
+		strbuf_addf(&buffer, "encoding %s\n", git_commit_encoding);
+	strbuf_addch(&buffer, '\n');
 
 	/* And add the comment */
-	while (fgets(comment, sizeof(comment), stdin) != NULL)
-		add_buffer(&buffer, &size, "%s", comment);
+	if (strbuf_read(&buffer, 0) < 0)
+		die("git-commit-tree: read returned %s", strerror(errno));
 
 	/* And check the encoding */
-	buffer[size] = '\0';
-	if (encoding_is_utf8 && !is_utf8(buffer))
+	if (encoding_is_utf8 && !is_utf8(buffer.buf))
 		fprintf(stderr, commit_utf8_warn);
 
-	if (!write_sha1_file(buffer, size, commit_type, commit_sha1)) {
+	if (!write_sha1_file(buffer.buf, buffer.len, commit_type, commit_sha1)) {
 		printf("%s\n", sha1_to_hex(commit_sha1));
 		return 0;
 	}
diff --git a/diff.c b/diff.c
index 0d30d05..c054b23 100644
--- a/diff.c
+++ b/diff.c
@@ -9,6 +9,7 @@
 #include "xdiff-interface.h"
 #include "color.h"
 #include "attr.h"
+#include "strbuf.h"
 
 #ifdef NO_FAST_WORKING_DIRECTORY
 #define FAST_WORKING_DIRECTORY 0
@@ -1545,26 +1546,16 @@ static int reuse_worktree_file(const char *name, const unsigned char *sha1, int
 
 static int populate_from_stdin(struct diff_filespec *s)
 {
-#define INCREMENT 1024
-	char *buf;
-	unsigned long size;
-	ssize_t got;
-
-	size = 0;
-	buf = NULL;
-	while (1) {
-		buf = xrealloc(buf, size + INCREMENT);
-		got = xread(0, buf + size, INCREMENT);
-		if (!got)
-			break; /* EOF */
-		if (got < 0)
-			return error("error while reading from stdin %s",
+	struct strbuf buf;
+
+	strbuf_init(&buf);
+	if (strbuf_read(&buf, 0) < 0)
+		return error("error while reading from stdin %s",
 				     strerror(errno));
-		size += got;
-	}
+
 	s->should_munmap = 0;
-	s->data = buf;
-	s->size = size;
+	s->size = buf.len;
+	s->data = strbuf_detach(&buf);
 	s->should_free = 1;
 	return 0;
 }
-- 
1.5.3.1
Previous: Pierre HabouzitNext: Pierre Habouzit
Message 50 of 90 in “strbuf API”
  1. Pierre HabouzitSep 2, 2007
  2. Johan HerlandSep 3, 2007
  3. Pierre HabouzitSep 3, 2007
  4. Miles BaderSep 4, 2007
  5. strbuf new semantics, let's give it a tryPierre Habouzit, Sep 4, 2007
  6. Rework strbuf API and semantics.Pierre Habouzit, Sep 4, 2007
  7. Johannes SchindelinSep 4, 2007
  8. Pierre HabouzitSep 4, 2007
  9. Andreas EricssonSep 4, 2007
  10. Rework strbuf API and semantics.Pierre Habouzit, Sep 4, 2007
  11. Johannes SchindelinSep 4, 2007
  12. Pierre HabouzitSep 4, 2007
  13. Wincent ColaiutaSep 4, 2007
  14. Simplify strbuf uses in fast-import.c using the proper functions.Pierre Habouzit, Sep 4, 2007
  15. René ScharfeSep 4, 2007
  16. René ScharfeSep 4, 2007
  17. Pierre HabouzitSep 5, 2007
  18. Junio C HamanoSep 5, 2007
  19. Pierre HabouzitSep 5, 2007
  20. Rework strbuf API and semantics.Pierre Habouzit, Sep 5, 2007
  21. Simplify strbuf uses in archive-tar.c using the proper functions.Pierre Habouzit, Sep 5, 2007
  22. Simplify strbuf uses in fast-import.c using the proper functions.Pierre Habouzit, Sep 5, 2007
  23. Use proper strbuf API, and also simplify cmd_data code.Pierre Habouzit, Sep 5, 2007
  24. Simplify write_tree using strbuf's.Pierre Habouzit, Sep 5, 2007
  25. Further strbuf re-engineering.Pierre Habouzit, Sep 5, 2007
  26. Eradicate yet-another-buffer implementation in buitin-rerere.cPierre Habouzit, Sep 5, 2007
  27. More strbuf uses in cache-tree.c.Pierre Habouzit, Sep 5, 2007
  28. Junio C HamanoSep 19, 2007
  29. Pierre HabouzitSep 5, 2007
  30. Junio C HamanoSep 19, 2007
  31. Pierre HabouzitSep 19, 2007
  32. Junio C HamanoSep 6, 2007
  33. Pierre HabouzitSep 6, 2007
  34. Junio C HamanoSep 6, 2007
  35. Pierre HabouzitSep 6, 2007
  36. Use proper strbuf API, and also simplify cmd_data code.Pierre Habouzit, Sep 4, 2007
  37. Miles BaderSep 5, 2007
  38. Add strbuf_fread, use it in fast-import.c.Pierre Habouzit, Sep 4, 2007
  39. Matthieu MoySep 3, 2007
  40. Pierre HabouzitSep 3, 2007
  41. Matthieu MoySep 3, 2007
  42. Junio C HamanoSep 3, 2007
  43. Pierre HabouzitSep 3, 2007
  44. Johannes SchindelinSep 3, 2007
  45. strbuf new API, take 2 for inclusionPierre Habouzit, Sep 6, 2007
  46. 1/7 Rework strbuf API and semantics.Pierre Habouzit, Sep 6, 2007
  47. 2/7 Simplify strbuf uses in archive-tar.c using the proper functions.Pierre Habouzit, Sep 6, 2007
  48. 3/7 Use proper strbuf API, and also simplify cmd_data code.Pierre Habouzit, Sep 6, 2007
  49. 4/7 Simplify write_tree using strbuf's.Pierre Habouzit, Sep 6, 2007
  50. 5/7 Further strbuf re-engineering.Pierre Habouzit, Sep 6, 2007
  51. 6/7 Eradicate yet-another-buffer implementation in buitin-rerere.cPierre Habouzit, Sep 6, 2007
  52. 7/7 More strbuf uses in cache-tree.c.Pierre Habouzit, Sep 6, 2007
  53. Johannes SchindelinSep 6, 2007
  54. Pierre HabouzitSep 6, 2007
  55. David KastrupSep 6, 2007
  56. Pierre HabouzitSep 6, 2007
  57. Junio C HamanoSep 7, 2007
  58. Pierre HabouzitSep 7, 2007
  59. Kristian HøgsbergSep 6, 2007
  60. Pierre HabouzitSep 6, 2007
  61. Kristian HøgsbergSep 6, 2007
  62. Pierre HabouzitSep 6, 2007
  63. René ScharfeSep 6, 2007
  64. Johannes SchindelinSep 6, 2007
  65. Jeff KingSep 6, 2007
  66. David KastrupSep 6, 2007
  67. Jeff KingSep 6, 2007
  68. David KastrupSep 6, 2007
  69. Jeff KingSep 6, 2007
  70. David KastrupSep 6, 2007
  71. Johannes SixtSep 6, 2007
  72. David KastrupSep 6, 2007
  73. Jeff KingSep 6, 2007
  74. Kristian HøgsbergSep 6, 2007
  75. Jeff KingSep 6, 2007
  76. Pierre HabouzitSep 6, 2007
  77. Jeff KingSep 6, 2007
  78. Pierre HabouzitSep 6, 2007
  79. Use strbufs in commit.c (pretty printing)Pierre Habouzit, Sep 8, 2007
  80. 1/3 Add strbuf_rtrim (to remove trailing spaces).Pierre Habouzit, Sep 8, 2007
  81. 2/3 Change semantics of interpolate to work like snprintf.Pierre Habouzit, Sep 8, 2007
  82. 3/3 Rework pretty_print_commit to use strbufs instead of custom buffers.Pierre Habouzit, Sep 8, 2007
  83. David KastrupSep 8, 2007
  84. Pierre HabouzitSep 8, 2007
  85. Pierre HabouzitSep 8, 2007
  86. René ScharfeSep 8, 2007
  87. Pierre HabouzitSep 8, 2007
  88. René ScharfeSep 8, 2007
  89. Pierre HabouzitSep 8, 2007
  90. Pierre HabouzitSep 8, 2007

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.