As suggested in the small project ideas [1], implement a --count-lines options for git stripspace to be able to omit calling git stripspace --strip-comments < infile | wc -l e.g. in git-rebase--interactive.sh. The above command can now be replaced by: git stripspace --strip-comments --count-lines < infile This will also make it easier to port git-rebase--interactive.sh to C later on. Furthermore, add the corresponding documentation and tests. [1] https://git.wiki.kernel.org/index.php/SmallProjectsIdeas#implement_.27--count-lines.27_in_.27git_stripspace.27 Signed-off-by: Tobias Klauser <tklauser@xxxxxxxxxx> --- Documentation/git-stripspace.txt | 13 ++++++++- builtin/stripspace.c | 57 ++++++++++++++++++++++------------------ strbuf.c | 12 ++++++--- strbuf.h | 5 ++-- t/t0030-stripspace.sh | 36 +++++++++++++++++++++++++ 5 files changed, 92 insertions(+), 31 deletions(-) diff --git a/Documentation/git-stripspace.txt b/Documentation/git-stripspace.txt index 60328d5..411e17c 100644 --- a/Documentation/git-stripspace.txt +++ b/Documentation/git-stripspace.txt @@ -9,7 +9,7 @@ git-stripspace - Remove unnecessary whitespace SYNOPSIS -------- [verse] -'git stripspace' [-s | --strip-comments] < input +'git stripspace' [-s | --strip-comments] [-C | --count-lines] < input 'git stripspace' [-c | --comment-lines] < input DESCRIPTION @@ -44,6 +44,11 @@ OPTIONS be terminated with a newline. On empty lines, only the comment character will be prepended. +-C:: +--count-lines:: + Output the number of resulting lines after stripping. This is equivalent + to calling 'git stripspace | wc -l'. + EXAMPLES -------- @@ -88,6 +93,12 @@ Use 'git stripspace --strip-comments' to obtain: |The end.$ --------- +Use 'git stripspace --count-lines' to obtain: + +--------- +|5$ +--------- + GIT --- Part of the linkgit:git[1] suite diff --git a/builtin/stripspace.c b/builtin/stripspace.c index f677093..7882edd 100644 --- a/builtin/stripspace.c +++ b/builtin/stripspace.c @@ -1,5 +1,6 @@ #include "builtin.h" #include "cache.h" +#include "parse-options.h" #include "strbuf.h" static void comment_lines(struct strbuf *buf) @@ -12,45 +13,51 @@ static void comment_lines(struct strbuf *buf) free(msg); } -static const char *usage_msg = "\n" -" git stripspace [-s | --strip-comments] < input\n" -" git stripspace [-c | --comment-lines] < input"; +static const char * const usage_msg[] = { + N_("git stripspace [-s | --strip-comments] [-C | --count-lines] < input"), + N_("git stripspace [-c | --comment-lines] < input"), + NULL +}; int cmd_stripspace(int argc, const char **argv, const char *prefix) { struct strbuf buf = STRBUF_INIT; - int strip_comments = 0; - enum { INVAL = 0, STRIP_SPACE = 1, COMMENT_LINES = 2 } mode = STRIP_SPACE; - - if (argc == 2) { - if (!strcmp(argv[1], "-s") || - !strcmp(argv[1], "--strip-comments")) { - strip_comments = 1; - } else if (!strcmp(argv[1], "-c") || - !strcmp(argv[1], "--comment-lines")) { - mode = COMMENT_LINES; - } else { - mode = INVAL; - } - } else if (argc > 1) { - mode = INVAL; - } + int comment_mode = 0, count_lines = 0, strip_comments = 0; + size_t lines = 0; + + const struct option options[] = { + OPT_BOOL('s', "strip-comments", &strip_comments, + N_("skip and remove all lines starting with comment character")), + OPT_BOOL('c', "comment-lines", &comment_mode, + N_("prepend comment character and blank to each line")), + OPT_BOOL('C', "count-lines", &count_lines, N_("print line count")), + OPT_END() + }; - if (mode == INVAL) - usage(usage_msg); + argc = parse_options(argc, argv, prefix, options, usage_msg, + PARSE_OPT_KEEP_DASHDASH); - if (strip_comments || mode == COMMENT_LINES) + if (comment_mode && (count_lines || strip_comments)) + usage_with_options(usage_msg, options); + + if (strip_comments || comment_mode) git_config(git_default_config, NULL); if (strbuf_read(&buf, 0, 1024) < 0) die_errno("could not read the input"); - if (mode == STRIP_SPACE) - strbuf_stripspace(&buf, strip_comments); + if (!comment_mode) + lines = strbuf_stripspace(&buf, strip_comments); else comment_lines(&buf); - write_or_die(1, buf.buf, buf.len); + if (!count_lines) + write_or_die(1, buf.buf, buf.len); + else { + struct strbuf tmp = STRBUF_INIT; + strbuf_addf(&tmp, "%zu\n", lines); + write_or_die(1, tmp.buf, tmp.len); + } strbuf_release(&buf); return 0; } diff --git a/strbuf.c b/strbuf.c index 9583875..45ea933 100644 --- a/strbuf.c +++ b/strbuf.c @@ -775,11 +775,13 @@ static size_t cleanup(char *line, size_t len) * * Enable skip_comments to skip every line starting with comment * character. + * + * Returns the number of lines in the resulting strbuf. */ -void strbuf_stripspace(struct strbuf *sb, int skip_comments) +size_t strbuf_stripspace(struct strbuf *sb, int skip_comments) { int empties = 0; - size_t i, j, len, newlen; + size_t i, j, len, newlen, lines = 0; char *eol; /* We may have to add a newline. */ @@ -797,15 +799,19 @@ void strbuf_stripspace(struct strbuf *sb, int skip_comments) /* Not just an empty line? */ if (newlen) { - if (empties > 0 && j > 0) + if (empties > 0 && j > 0) { sb->buf[j++] = '\n'; + lines++; + } empties = 0; memmove(sb->buf + j, sb->buf + i, newlen); sb->buf[newlen + j++] = '\n'; + lines++; } else { empties++; } } strbuf_setlen(sb, j); + return lines; } diff --git a/strbuf.h b/strbuf.h index 5397d91..7d33f39 100644 --- a/strbuf.h +++ b/strbuf.h @@ -416,9 +416,10 @@ extern void strbuf_add_absolute_path(struct strbuf *sb, const char *path); /** * Strip whitespace from a buffer. The second parameter controls if - * comments are considered contents to be removed or not. + * comments are considered contents to be removed or not. Returns the + * number of lines in the resulting buffer. */ -extern void strbuf_stripspace(struct strbuf *buf, int skip_comments); +extern size_t strbuf_stripspace(struct strbuf *buf, int skip_comments); /** * Temporary alias until all topic branches have switched to use diff --git a/t/t0030-stripspace.sh b/t/t0030-stripspace.sh index 29e91d8..5471a5a 100755 --- a/t/t0030-stripspace.sh +++ b/t/t0030-stripspace.sh @@ -438,4 +438,40 @@ test_expect_success 'avoid SP-HT sequence in commented line' ' test_cmp expect actual ' +test_expect_success '--count-lines with newline only' ' + printf "0\n" >expect && + printf "\n" | git stripspace -C >actual && + test_cmp expect actual +' + +test_expect_success '--count-lines with single line' ' + printf "1\n" >expect && + printf "foo\n" | git stripspace -C >actual && + test_cmp expect actual +' + +test_expect_success '--count-lines with single line preceeded by empty line' ' + printf "1\n" >expect && + printf "\nfoo" | git stripspace -C >actual && + test_cmp expect actual +' + +test_expect_success '--count-lines with single line followed by empty line' ' + printf "1\n" >expect && + printf "foo\n\n" | git stripspace -C >actual && + test_cmp expect actual +' + +test_expect_success '--count-lines with multiple lines and consecutive newlines' ' + printf "5\n" >expect && + printf "\none\n\n\nthree\nfour\nfive\n" | git stripspace -C >actual && + test_cmp expect actual +' + +test_expect_success '--count-lines combined with --strip-comments' ' + printf "5\n" >expect && + printf "\n# stripped\none\n#stripped\n\nthree\nfour\nfive\n" | git stripspace -s -C >actual && + test_cmp expect actual +' + test_done -- 2.6.1.145.gb27dacc -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html