diff options
Diffstat (limited to 'strbuf.c')
-rw-r--r-- | strbuf.c | 66 |
1 files changed, 66 insertions, 0 deletions
@@ -752,3 +752,69 @@ void strbuf_add_unique_abbrev(struct strbuf *sb, const unsigned char *sha1, r = find_unique_abbrev_r(sb->buf + sb->len, sha1, abbrev_len); strbuf_setlen(sb, sb->len + r); } + +/* + * Returns the length of a line, without trailing spaces. + * + * If the line ends with newline, it will be removed too. + */ +static size_t cleanup(char *line, size_t len) +{ + while (len) { + unsigned char c = line[len - 1]; + if (!isspace(c)) + break; + len--; + } + + return len; +} + +/* + * Remove empty lines from the beginning and end + * and also trailing spaces from every line. + * + * Turn multiple consecutive empty lines between paragraphs + * into just one empty line. + * + * If the input has only empty lines and spaces, + * no output will be produced. + * + * If last line does not have a newline at the end, one is added. + * + * Enable skip_comments to skip every line starting with comment + * character. + */ +void strbuf_stripspace(struct strbuf *sb, int skip_comments) +{ + int empties = 0; + size_t i, j, len, newlen; + char *eol; + + /* We may have to add a newline. */ + strbuf_grow(sb, 1); + + for (i = j = 0; i < sb->len; i += len, j += newlen) { + eol = memchr(sb->buf + i, '\n', sb->len - i); + len = eol ? eol - (sb->buf + i) + 1 : sb->len - i; + + if (skip_comments && len && sb->buf[i] == comment_line_char) { + newlen = 0; + continue; + } + newlen = cleanup(sb->buf + i, len); + + /* Not just an empty line? */ + if (newlen) { + if (empties > 0 && j > 0) + sb->buf[j++] = '\n'; + empties = 0; + memmove(sb->buf + j, sb->buf + i, newlen); + sb->buf[newlen + j++] = '\n'; + } else { + empties++; + } + } + + strbuf_setlen(sb, j); +} |