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