diff --git a/app/src/util/str.c b/app/src/util/str.c index 1564ffe2..70e3f1de 100644 --- a/app/src/util/str.c +++ b/app/src/util/str.c @@ -330,3 +330,14 @@ sc_str_index_of_column(const char *s, unsigned col, const char *seps) { return col == colidx ? (ssize_t) idx : -1; } + +size_t +sc_str_remove_trailing_cr(char *s, size_t len) { + while (len) { + if (s[len - 1] != '\r') { + break; + } + s[--len] = '\0'; + } + return len; +} diff --git a/app/src/util/str.h b/app/src/util/str.h index 2c7d7829..b81764ef 100644 --- a/app/src/util/str.h +++ b/app/src/util/str.h @@ -134,4 +134,15 @@ sc_str_truncate(char *data, size_t len, const char *endchars); ssize_t sc_str_index_of_column(const char *s, unsigned col, const char *seps); +/** + * Remove all `\r` at the end of the line + * + * The line length is provided by `len` (this avoids a call to `strlen()` when + * the caller already knows the length). + * + * Return the new length. + */ +size_t +sc_str_remove_trailing_cr(char *s, size_t len); + #endif diff --git a/app/tests/test_str.c b/app/tests/test_str.c index bd976b3c..cc3039e7 100644 --- a/app/tests/test_str.c +++ b/app/tests/test_str.c @@ -384,6 +384,20 @@ static void test_index_of_column(void) { assert(sc_str_index_of_column(" a bc d", 1, " ") == 2); } +static void test_remove_trailing_cr() { + char s[] = "abc\r"; + sc_str_remove_trailing_cr(s, sizeof(s) - 1); + assert(!strcmp(s, "abc")); + + char s2[] = "def\r\r\r\r"; + sc_str_remove_trailing_cr(s2, sizeof(s2) - 1); + assert(!strcmp(s2, "def")); + + char s3[] = "adb\rdef\r"; + sc_str_remove_trailing_cr(s3, sizeof(s3) - 1); + assert(!strcmp(s3, "adb\rdef")); +} + int main(int argc, char *argv[]) { (void) argc; (void) argv; @@ -405,5 +419,6 @@ int main(int argc, char *argv[]) { test_wrap_lines(); test_truncate(); test_index_of_column(); + test_remove_trailing_cr(); return 0; }