summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2015-10-28 13:17:29 -0700
committerJunio C Hamano <gitster@pobox.com>2016-01-14 15:05:55 -0800
commitc8aa9fdf5dc15e2c508acb22df03d431983569ed (patch)
tree1d905b7200f02f7ae4bdd8966ec849e8ff1c52dc
parentdce80bd18cae17b2d5645e3a9c40e76f905fd643 (diff)
downloadgit-c8aa9fdf5dc15e2c508acb22df03d431983569ed.tar.gz
strbuf: make strbuf_getline_crlf() global
Often we read "text" files that are supplied by the end user (e.g. commit log message that was edited with $GIT_EDITOR upon 'git commit -e'), and in some environments lines in a text file are terminated with CRLF. Existing strbuf_getline() knows to read a single line and then strip the terminating byte from the result, but it is handy to have a version that is more tailored for a "text" input that takes both '\n' and '\r\n' as line terminator (aka <newline> in POSIX lingo) and returns the body of the line after stripping <newline>. Recently reimplemented "git am" uses such a function implemented privately; move it to strbuf.[ch] and make it available for others. Note that we do not blindly replace calls to strbuf_getline() that uses LF as the line terminator with calls to strbuf_getline_crlf() and this is very much deliberate. Some callers may want to treat an incoming line that ends with CR (and terminated with LF) to have a payload that includes the final CR, and such a blind replacement will result in misconversion when done without code audit. Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--builtin/am.c15
-rw-r--r--strbuf.c12
-rw-r--r--strbuf.h7
3 files changed, 19 insertions, 15 deletions
diff --git a/builtin/am.c b/builtin/am.c
index 9fb42fdd71..d96735c0be 100644
--- a/builtin/am.c
+++ b/builtin/am.c
@@ -46,21 +46,6 @@ static int is_empty_file(const char *filename)
}
/**
- * Like strbuf_getline(), but treats both '\n' and "\r\n" as line terminators.
- */
-static int strbuf_getline_crlf(struct strbuf *sb, FILE *fp)
-{
- if (strbuf_getwholeline(sb, fp, '\n'))
- return EOF;
- if (sb->buf[sb->len - 1] == '\n') {
- strbuf_setlen(sb, sb->len - 1);
- if (sb->len > 0 && sb->buf[sb->len - 1] == '\r')
- strbuf_setlen(sb, sb->len - 1);
- }
- return 0;
-}
-
-/**
* Returns the length of the first line of msg.
*/
static int linelen(const char *msg)
diff --git a/strbuf.c b/strbuf.c
index b165d044ae..7ad5ea4145 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -510,6 +510,18 @@ int strbuf_getline(struct strbuf *sb, FILE *fp, int term)
return 0;
}
+int strbuf_getline_crlf(struct strbuf *sb, FILE *fp)
+{
+ if (strbuf_getwholeline(sb, fp, '\n'))
+ return EOF;
+ if (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);
+ }
+ return 0;
+}
+
int strbuf_getwholeline_fd(struct strbuf *sb, int fd, int term)
{
strbuf_reset(sb);
diff --git a/strbuf.h b/strbuf.h
index 7123fca7af..d84c866ab1 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -388,6 +388,13 @@ extern int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint);
*/
extern int strbuf_getline(struct strbuf *, FILE *, int);
+/*
+ * Similar to strbuf_getline(), but uses '\n' as the terminator,
+ * and additionally treats a '\r' that comes immediately before '\n'
+ * as part of the terminator.
+ */
+extern int strbuf_getline_crlf(struct strbuf *, FILE *);
+
/**
* Like `strbuf_getline`, but keeps the trailing terminator (if
* any) in the buffer.