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

Re: [PATCH 01/10] strbuf_split: add a max parameter

From
Junio C Hamano <gitster@pobox.com>
Date
Jun 13, 2011, 17:30 UTC
Message-ID
<7voc21od0g.fsf@alter.siamese.dyndns.org>
In-Reply-To
<20110609155121.GA25507@sigill.intra.peff.net>
Jeff King <peff@peff.net> writes:
> I am tempted to just call this new one strbuf_split and update all
> callers. There aren't that many.

Yes, that is indeed tempting, and because we have a new parameter the compiler will catch any new callers that pop up in a mismerge so that would be perfectly safe.

Show 17 quoted lines
> -struct strbuf **strbuf_split(const struct strbuf *sb, int delim)
> +struct strbuf **strbuf_split_max(const struct strbuf *sb, int delim, int max)
>  {
>  	int alloc = 2, pos = 0;
>  	char *n, *p;
> @@ -114,7 +114,10 @@ struct strbuf **strbuf_split(const struct strbuf *sb, int delim)
>  	p = n = sb->buf;
>  	while (n < sb->buf + sb->len) {
>  		int len;
> -		n = memchr(n, delim, sb->len - (n - sb->buf));
> +		if (max <= 0 || pos + 1 < max)
> +			n = memchr(n, delim, sb->len - (n - sb->buf));
> +		else
> +			n = NULL;
>  		if (pos + 1 >= alloc) {
>  			alloc = alloc * 2;
>  			ret = xrealloc(ret, sizeof(struct strbuf *) * alloc);

Hmm, even when we know the value of max, we go exponential, and even do so by hand without using ALLOC_GROW(). Somewhat sad.

Also do we currently rely on the bug that strbuf_split() returns (NULL,) instead of ("", NULL) when given an empty string? If not, perhaps...

 strbuf.c |   50 +++++++++++++++++++++++++++++++-------------------
 1 files changed, 31 insertions(+), 19 deletions(-)
diff --git a/strbuf.c b/strbuf.c
index 09c43ae..7a8ee3a 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -103,31 +103,43 @@ void strbuf_ltrim(struct strbuf *sb)
 	sb->buf[sb->len] = '\0';
 }
 
-struct strbuf **strbuf_split(const struct strbuf *sb, int delim)
+struct strbuf **strbuf_split_max(const struct strbuf *sb, int delim, int max)
 {
-	int alloc = 2, pos = 0;
 	char *n, *p;
-	struct strbuf **ret;
+	struct strbuf **ret = NULL;
 	struct strbuf *t;
-
-	ret = xcalloc(alloc, sizeof(struct strbuf *));
-	p = n = sb->buf;
-	while (n < sb->buf + sb->len) {
-		int len;
-		n = memchr(n, delim, sb->len - (n - sb->buf));
-		if (pos + 1 >= alloc) {
-			alloc = alloc * 2;
-			ret = xrealloc(ret, sizeof(struct strbuf *) * alloc);
+	int pass, count = 0;
+
+	for (pass = 0; pass < 2; pass++) {
+		/* First pass counts, second pass allocates and fills */
+		if (pass)
+			ret = xcalloc(count + 1 + !count, sizeof(struct strbuf *));
+		count = 0;
+		n = sb->buf;
+		while (n < sb->buf + sb->len) {
+			p = n;
+			if (max <= 0 || count + 1 < max)
+				n = memchr(n, delim, sb->len - (n - sb->buf));
+			else
+				n = NULL;
+			if (!n)
+				n = sb->buf + sb->len - 1;
+
+			if (pass) {
+				int len = n - p + 1;
+				t = xmalloc(sizeof(struct strbuf));
+				strbuf_init(t, len);
+				strbuf_add(t, p, len);
+				ret[count] = t;
+			}
+			count++;
+			n++;
 		}
-		if (!n)
-			n = sb->buf + sb->len - 1;
-		len = n - p + 1;
+	}
+	if (!count) {
 		t = xmalloc(sizeof(struct strbuf));
-		strbuf_init(t, len);
-		strbuf_add(t, p, len);
-		ret[pos] = t;
-		ret[++pos] = NULL;
-		p = ++n;
+		strbuf_init(t, 0);
+		ret[0] = t;
 	}
 	return ret;
 }
Previous: Jeff KingNext: Jeff King
Message 7 of 25 in “Git-Mediawiki : cloning a set of pages”
  1. Claire FousseJun 8, 2011
  2. Jeff KingJun 8, 2011
  3. Sverre RabbelierJun 8, 2011
  4. Jeff KingJun 8, 2011
  5. Jeff KingJun 9, 2011
  6. 01/10 strbuf_split: add a max parameterJeff King, Jun 9, 2011
  7. Junio C HamanoJun 13, 2011
  8. Jeff KingJun 13, 2011
  9. 02/10 fix "git -c" parsing of values with equals signsJeff King, Jun 9, 2011
  10. 03/10 config: die on error in command-line configJeff King, Jun 9, 2011
  11. 04/10 config: avoid segfault when parsing command-line configJeff King, Jun 9, 2011
  12. Junio C HamanoJun 13, 2011
  13. Jeff KingJun 13, 2011
  14. 05/10 strbuf: allow strbuf_split to work on non-strbufsJeff King, Jun 9, 2011
  15. 06/10 config: use strbuf_split_str instead of a temporary strbufJeff King, Jun 9, 2011
  16. 07/10 parse-options: add OPT_STRING_LIST helperJeff King, Jun 9, 2011
  17. 08/10 remote: use new OPT_STRING_LISTJeff King, Jun 9, 2011
  18. 09/10 config: make git_config_parse_parameter a public functionJeff King, Jun 9, 2011
  19. 10/10 clone: accept config options on the command lineJeff King, Jun 9, 2011
  20. Bert WesargJun 9, 2011
  21. Jeff KingJun 9, 2011
  22. Jeff KingJun 9, 2011
  23. Matthieu MoyJun 9, 2011
  24. Jakub NarebskiJun 8, 2011
  25. Claire FousseJun 9, 2011

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.