aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/api/private/helpers.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/api/private/helpers.c')
-rw-r--r--src/nvim/api/private/helpers.c31
1 files changed, 22 insertions, 9 deletions
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index 3443f85e20..2e4874d7c6 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -745,19 +745,32 @@ String ga_take_string(garray_T *ga)
return str;
}
-/// Creates "readfile()-style" ArrayOf(String).
+/// Creates "readfile()-style" ArrayOf(String) from a binary string.
///
-/// - NUL bytes are replaced with NL (form-feed).
-/// - If last line ends with NL an extra empty list item is added.
-Array string_to_array(const String input)
+/// - Lines break at \n (NL/LF/line-feed).
+/// - NUL bytes are replaced with NL.
+/// - If the last byte is a linebreak an extra empty list item is added.
+///
+/// @param input Binary string
+/// @param crlf Also break lines at CR and CRLF.
+/// @return [allocated] String array
+Array string_to_array(const String input, bool crlf)
{
Array ret = ARRAY_DICT_INIT;
for (size_t i = 0; i < input.size; i++) {
const char *start = input.data + i;
- const char *end = xmemscan(start, NL, input.size - i);
- const size_t line_len = (size_t)(end - start);
+ const char *end = start;
+ size_t line_len = 0;
+ for (; line_len < input.size - i; line_len++) {
+ end = start + line_len;
+ if (*end == NL || (crlf && *end == CAR)) {
+ break;
+ }
+ }
i += line_len;
-
+ if (crlf && *end == CAR && i + 1 < input.size && *(end + 1) == NL) {
+ i += 1; // Advance past CRLF.
+ }
String s = {
.size = line_len,
.data = xmemdupz(start, line_len),
@@ -766,8 +779,8 @@ Array string_to_array(const String input)
ADD(ret, STRING_OBJ(s));
// If line ends at end-of-buffer, add empty final item.
// This is "readfile()-style", see also ":help channel-lines".
- if (i + 1 == input.size && end[0] == NL) {
- ADD(ret, STRING_OBJ(cchar_to_string(NUL)));
+ if (i + 1 == input.size && (*end == NL || (crlf && *end == CAR))) {
+ ADD(ret, STRING_OBJ(STRING_INIT));
}
}