Skip to content

Commit af35e56

Browse files
pks-tgitster
authored andcommitted
strbuf: provide CRLF-aware helper to read until a specified delimiter
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b116c77 commit af35e56

File tree

2 files changed

+20
-3
lines changed

2 files changed

+20
-3
lines changed

strbuf.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -721,18 +721,23 @@ static int strbuf_getdelim(struct strbuf *sb, FILE *fp, int term)
721721
return 0;
722722
}
723723

724-
int strbuf_getline(struct strbuf *sb, FILE *fp)
724+
int strbuf_getdelim_strip_crlf(struct strbuf *sb, FILE *fp, int term)
725725
{
726-
if (strbuf_getwholeline(sb, fp, '\n'))
726+
if (strbuf_getwholeline(sb, fp, term))
727727
return EOF;
728-
if (sb->buf[sb->len - 1] == '\n') {
728+
if (term == '\n' && sb->buf[sb->len - 1] == '\n') {
729729
strbuf_setlen(sb, sb->len - 1);
730730
if (sb->len && sb->buf[sb->len - 1] == '\r')
731731
strbuf_setlen(sb, sb->len - 1);
732732
}
733733
return 0;
734734
}
735735

736+
int strbuf_getline(struct strbuf *sb, FILE *fp)
737+
{
738+
return strbuf_getdelim_strip_crlf(sb, fp, '\n');
739+
}
740+
736741
int strbuf_getline_lf(struct strbuf *sb, FILE *fp)
737742
{
738743
return strbuf_getdelim(sb, fp, '\n');

strbuf.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,18 @@ int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint);
475475
*/
476476
ssize_t strbuf_write(struct strbuf *sb, FILE *stream);
477477

478+
/**
479+
* Read from a FILE * until the specified terminator is encountered,
480+
* overwriting the existing contents of the strbuf.
481+
*
482+
* Reading stops after the terminator or at EOF. The terminator is
483+
* removed from the buffer before returning. If the terminator is LF
484+
* and if it is preceded by a CR, then the whole CRLF is stripped.
485+
* Returns 0 unless there was nothing left before EOF, in which case
486+
* it returns `EOF`.
487+
*/
488+
int strbuf_getdelim_strip_crlf(struct strbuf *sb, FILE *fp, int term);
489+
478490
/**
479491
* Read a line from a FILE *, overwriting the existing contents of
480492
* the strbuf. The strbuf_getline*() family of functions share

0 commit comments

Comments
 (0)