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

Re: [PATCH 3/9] strbuf: provide function to append whole lines

From
Junio C Hamano <gitster@pobox.com>
Date
Mar 27, 2020, 21:04 UTC
Message-ID
<xmqqpncxfr1p.fsf@gitster.c.googlers.com>
In-Reply-To
<4b0a963ea5c47a951b95aa0a03966315b3e8299d.1585129842.git.ps@pks.im>
Patrick Steinhardt <ps@pks.im> writes:
Show 9 quoted lines
> While the strbuf interface already provides functions to read a line
> into it that completely replaces its current contents, we do not have an
> interface that allows for appending lines without discarding current
> contents.
>
> Add a new function `strbuf_appendwholeline` that reads a line including
> its terminating character into a strbuf non-destructively. This is a
> preparatory step for git-update-ref(1) reading standard input line-wise
> instead of as a block.

Hmph. If we were to gain more uses of this function over time, the necessity for an extra strbuf_addbuf() becomes annoying. I wonder if we should be doing this patch the other way around, i.e. move the whole implementation, except for the early

	if (feof(fp))
		return EOF;
	strbuf_reset(sb);

part, and call it strbuf_addwholeline(), and strbuf_getwholeline() becomes a thin wrapper around it that resets the incoming buffer before calling strbuf_addwholeline(). The logic to determine EOF would need to be updated if we go that route (i.e. instead of checking sb->len is zero in the !HAVE_GETDELIM side of the implementation, we need to see if the number is the same as before) but it should be minor.

There is a stale comment in the HAVE_GETDELIM side of the curent implementation, by the way. I think our xrealloc no longer tries to "recover" from ENOMEM.

Having said all that, I am fine with this version, at least for now.
Show 5 quoted lines
> +int strbuf_appendwholeline(struct strbuf *sb, FILE *fp, int term)
> +{
> +	struct strbuf line = STRBUF_INIT;
> +	if (strbuf_getwholeline(&line, fp, term))
> +		return EOF;
So, if caller wants to read the stream until it runs out, it can do
	strbuf_init(&sb);
	while (strbuf_appendwholeline(&sb, fp, '\n') != EOF)
		; /* keep going */

If the caller knows how many lines to read, EOF-return can be used only for error checking, e.g.

	strbuf_init(&sb);
	for (count = 0; count < 5; count++)
		if (strbuf_appendwholeline(&sb, fp, '\n') == EOF)
			die("cannot grab 5 lines");

It becomes cumbersome if the input lines are terminated, though. The caller wouldn't be using strbuf_appendwholeline() interface, e.g.

	strbuf_init(&accum);
	while ((strbuf_getwholeline(&sb, fp, '\n') != EOF) &&
               strcmp(sb.buf, "done\n"))
		strbuf_addbuf(&accum, &sb);

Anyway, I was primarily wondering if returning EOF, which perfectly makes sense for getwholeline(), still makes sense for addwholeline(), and it seems that it is still useful.

Show 25 quoted lines
> +	strbuf_addbuf(sb, &line);
> +	strbuf_release(&line);
> +	return 0;
> +}
> +
>  static int strbuf_getdelim(struct strbuf *sb, FILE *fp, int term)
>  {
>  	if (strbuf_getwholeline(sb, fp, term))
> diff --git a/strbuf.h b/strbuf.h
> index ce8e49c0b2..411063ca76 100644
> --- a/strbuf.h
> +++ b/strbuf.h
> @@ -502,6 +502,12 @@ int strbuf_getline(struct strbuf *sb, FILE *file);
>   */
>  int strbuf_getwholeline(struct strbuf *sb, FILE *file, int term);
>  
> +/**
> + * Like `strbuf_getwholeline`, but appends the line instead of
> + * resetting the buffer first.
> + */
> +int strbuf_appendwholeline(struct strbuf *sb, FILE *file, int term);
> +
>  /**
>   * Like `strbuf_getwholeline`, but operates on a file descriptor.
>   * It reads one character at a time, so it is very slow.  Do not
Previous: Patrick SteinhardtNext: Patrick Steinhardt
Message 6 of 48 in “Support for transactions in `git-update-ref --stdin`”
  1. 0/9 Support for transactions in `git-update-ref --stdin`Patrick Steinhardt, Mar 25, 2020
  2. 1/9 refs: fix segfault when aborting empty transactionPatrick Steinhardt, Mar 25, 2020
  3. Junio C HamanoMar 27, 2020
  4. 2/9 git-update-ref.txt: add missing wordPatrick Steinhardt, Mar 25, 2020
  5. 3/9 strbuf: provide function to append whole linesPatrick Steinhardt, Mar 25, 2020
  6. Junio C HamanoMar 27, 2020
  7. Patrick SteinhardtMar 30, 2020
  8. Junio C HamanoMar 30, 2020
  9. 4/9 update-ref: organize commands in an arrayPatrick Steinhardt, Mar 25, 2020
  10. Junio C HamanoMar 27, 2020
  11. Patrick SteinhardtMar 30, 2020
  12. Junio C HamanoMar 30, 2020
  13. Patrick SteinhardtMar 30, 2020
  14. 5/9 update-ref: drop unused argument for `parse_refname`Patrick Steinhardt, Mar 25, 2020
  15. 6/9 update-ref: pass end pointer instead of strbufPatrick Steinhardt, Mar 25, 2020
  16. 7/9 update-ref: move transaction handling into `update_refs_stdin()`Patrick Steinhardt, Mar 25, 2020
  17. Junio C HamanoMar 27, 2020
  18. 8/9 update-ref: read commands in a line-wise fashionPatrick Steinhardt, Mar 25, 2020
  19. Junio C HamanoMar 27, 2020
  20. Patrick SteinhardtMar 30, 2020
  21. Junio C HamanoMar 30, 2020
  22. 9/9 update-ref: implement interactive transaction handlingPatrick Steinhardt, Mar 25, 2020
  23. Junio C HamanoMar 27, 2020
  24. 0/9 Support for transactions in `git-update-ref --stdin`Patrick Steinhardt, Mar 30, 2020
  25. 1/9 refs: fix segfault when aborting empty transactionPatrick Steinhardt, Mar 30, 2020
  26. 2/9 git-update-ref.txt: add missing wordPatrick Steinhardt, Mar 30, 2020
  27. 3/9 strbuf: provide function to append whole linesPatrick Steinhardt, Mar 30, 2020
  28. 4/9 update-ref: organize commands in an arrayPatrick Steinhardt, Mar 30, 2020
  29. 5/9 update-ref: drop unused argument for `parse_refname`Patrick Steinhardt, Mar 30, 2020
  30. 6/9 update-ref: pass end pointer instead of strbufPatrick Steinhardt, Mar 30, 2020
  31. 7/9 update-ref: move transaction handling into `update_refs_stdin()`Patrick Steinhardt, Mar 30, 2020
  32. 8/9 update-ref: read commands in a line-wise fashionPatrick Steinhardt, Mar 30, 2020
  33. 9/9 update-ref: implement interactive transaction handlingPatrick Steinhardt, Mar 30, 2020
  34. 0/9 Support for transactions in `git-update-ref --stdin`Patrick Steinhardt, Apr 2, 2020
  35. 1/9 refs: fix segfault when aborting empty transactionPatrick Steinhardt, Apr 2, 2020
  36. 2/9 git-update-ref.txt: add missing wordPatrick Steinhardt, Apr 2, 2020
  37. 3/9 strbuf: provide function to append whole linesPatrick Steinhardt, Apr 2, 2020
  38. 4/9 update-ref: organize commands in an arrayPatrick Steinhardt, Apr 2, 2020
  39. 5/9 update-ref: drop unused argument for `parse_refname`Patrick Steinhardt, Apr 2, 2020
  40. 6/9 update-ref: pass end pointer instead of strbufPatrick Steinhardt, Apr 2, 2020
  41. 7/9 update-ref: move transaction handling into `update_refs_stdin()`Patrick Steinhardt, Apr 2, 2020
  42. 8/9 update-ref: read commands in a line-wise fashionPatrick Steinhardt, Apr 2, 2020
  43. 9/9 update-ref: implement interactive transaction handlingPatrick Steinhardt, Apr 2, 2020
  44. Phillip WoodApr 3, 2020
  45. Patrick SteinhardtApr 3, 2020
  46. Junio C HamanoApr 3, 2020
  47. Junio C HamanoApr 3, 2020
  48. Patrick SteinhardtApr 6, 2020

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.