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

[PATCH 3/5] strbuf: provide CRLF-aware helper to read until a specified delimiter

From
Patrick Steinhardt <ps@pks.im>
Date
Jun 2, 2023, 13:02 UTC
Message-ID
<8127eeac97200da9aafccdf16cb7ba06f68b0121.1685710884.git.ps@pks.im>
In-Reply-To
<cover.1685710884.git.ps@pks.im>

Many of our commands support reading input that is separated either via newlines or via NUL characters. Furthermore, in order to be a better cross platform citizen, these commands typically know to strip the CRLF sequence so that we also support reading newline-separated inputs on e.g. the Windows platform. This results in the following kind of awkward pattern:

``` struct strbuf input = STRBUF_INIT;

while (1) {
	int ret;
	if (nul_terminated)
		ret = strbuf_getline_nul(&input, stdin);
	else
		ret = strbuf_getline(&input, stdin);
	if (ret)
		break;
	...
}
```

Introduce a new CRLF-aware helper function that can read up to a user specified delimiter. If the delimiter is `\n` the function knows to also strip CRLF, otherwise it will only strip the specified delimiter. This results in the following, much more readable code pattern:

``` struct strbuf input = STRBUF_INIT;

while (strbuf_getdelim_strip_crlf(&input, stdin, delim) != EOF) {
	...
}
```
The new function will be used in a subsequent commit.
Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
 strbuf.c | 11 ++++++++---
 strbuf.h | 12 ++++++++++++
 2 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/strbuf.c b/strbuf.c
index 08eec8f1d8..31dc48c0ab 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -721,11 +721,11 @@ static int strbuf_getdelim(struct strbuf *sb, FILE *fp, int term)
 	return 0;
 }
 
-int strbuf_getline(struct strbuf *sb, FILE *fp)
+int strbuf_getdelim_strip_crlf(struct strbuf *sb, FILE *fp, int term)
 {
-	if (strbuf_getwholeline(sb, fp, '\n'))
+	if (strbuf_getwholeline(sb, fp, term))
 		return EOF;
-	if (sb->buf[sb->len - 1] == '\n') {
+	if (term == '\n' && sb->buf[sb->len - 1] == '\n') {
 		strbuf_setlen(sb, sb->len - 1);
 		if (sb->len && sb->buf[sb->len - 1] == '\r')
 			strbuf_setlen(sb, sb->len - 1);
@@ -733,6 +733,11 @@ int strbuf_getline(struct strbuf *sb, FILE *fp)
 	return 0;
 }
 
+int strbuf_getline(struct strbuf *sb, FILE *fp)
+{
+	return strbuf_getdelim_strip_crlf(sb, fp, '\n');
+}
+
 int strbuf_getline_lf(struct strbuf *sb, FILE *fp)
 {
 	return strbuf_getdelim(sb, fp, '\n');
diff --git a/strbuf.h b/strbuf.h
index 3dfeadb44c..0e69b656bc 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -475,6 +475,18 @@ int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint);
  */
 ssize_t strbuf_write(struct strbuf *sb, FILE *stream);
 
+/**
+ * Read from a FILE * until the specified terminator is encountered,
+ * overwriting the existing contents of the strbuf.
+ *
+ * Reading stops after the terminator or at EOF.  The terminator is
+ * removed from the buffer before returning.  If the terminator is LF
+ * and if it is preceded by a CR, then the whole CRLF is stripped.
+ * Returns 0 unless there was nothing left before EOF, in which case
+ * it returns `EOF`.
+ */
+int strbuf_getdelim_strip_crlf(struct strbuf *sb, FILE *fp, int term);
+
 /**
  * Read a line from a FILE *, overwriting the existing contents of
  * the strbuf.  The strbuf_getline*() family of functions share
-- 
2.40.1
Previous: Patrick SteinhardtNext: Patrick Steinhardt
Message 4 of 22 in “cat-file: introduce NUL-terminated output format”
  1. 0/5 cat-file: introduce NUL-terminated output formatPatrick Steinhardt, Jun 2, 2023
  2. 1/5 t1006: don't strip timestamps from expected resultsPatrick Steinhardt, Jun 2, 2023
  3. 2/5 t1006: modernize test style to use `test_cmp`Patrick Steinhardt, Jun 2, 2023
  4. 3/5 strbuf: provide CRLF-aware helper to read until a specified delimiterPatrick Steinhardt, Jun 2, 2023
  5. 4/5 cat-file: simplify reading from standard inputPatrick Steinhardt, Jun 2, 2023
  6. 5/5 cat-file: Introduce new option to delimit output with NUL charactersPatrick Steinhardt, Jun 2, 2023
  7. Phillip WoodJun 5, 2023
  8. Junio C HamanoJun 5, 2023
  9. Patrick SteinhardtJun 6, 2023
  10. Junio C HamanoJun 6, 2023
  11. Patrick SteinhardtJun 6, 2023
  12. Junio C HamanoJun 12, 2023
  13. Patrick SteinhardtJun 6, 2023
  14. Junio C HamanoJun 6, 2023
  15. Junio C HamanoJun 3, 2023
  16. 0/5 catfile: introduce NUL-terminated output formatPatrick Steinhardt, Jun 6, 2023
  17. 1/5 t1006: don't strip timestamps from expected resultsPatrick Steinhardt, Jun 6, 2023
  18. 2/5 t1006: modernize test style to use `test_cmp`Patrick Steinhardt, Jun 6, 2023
  19. 3/5 strbuf: provide CRLF-aware helper to read until a specified delimiterPatrick Steinhardt, Jun 6, 2023
  20. 4/5 cat-file: simplify reading from standard inputPatrick Steinhardt, Jun 6, 2023
  21. 5/5 cat-file: introduce option to delimit input and output with NULPatrick Steinhardt, Jun 6, 2023
  22. Junio C HamanoJun 12, 2023

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.