* [PATCH 0/3] stripspace: Implement and use --count-lines option
@ 2015-10-15 12:18 Tobias Klauser
2015-10-15 12:18 ` [PATCH 1/3] strbuf: make stripspace() part of strbuf Tobias Klauser
` (2 more replies)
0 siblings, 3 replies; 19+ messages in thread
From: Tobias Klauser @ 2015-10-15 12:18 UTC (permalink / raw)
To: Junio C Hamano, Matthieu Moy, git
This patch set implements some of the project ideas around git stripspace
suggested on [1].
[1] https://git.wiki.kernel.org/index.php/SmallProjectsIdeas
The first patch moves the stripspace() function to the
strbuf module (adding a prefix and changing all users accordingly, also
a wrapper is introduced in case any topic branches still depend on the
old name). The second patch introduces option --count-lines to git
stripspace and also adds documentation and tests accordingly, Finally,
the third patch changes git-rebase--interactive.sh to replace commands
like:
git stripspace ... | wc -l
with:
git stripspace --count-lines ...
Tobias Klauser (3):
strbuf: make stripspace() part of strbuf
stripspace: Implement --count-lines option
git rebase -i: Use newly added --count-lines option for stripspace
Documentation/git-stripspace.txt | 13 ++++-
builtin/am.c | 2 +-
builtin/branch.c | 2 +-
builtin/commit.c | 6 +-
builtin/merge.c | 2 +-
builtin/notes.c | 6 +-
builtin/stripspace.c | 122 ++++++++++-----------------------------
builtin/tag.c | 2 +-
git-rebase--interactive.sh | 6 +-
strbuf.c | 72 +++++++++++++++++++++++
strbuf.h | 14 ++++-
t/t0030-stripspace.sh | 36 ++++++++++++
12 files changed, 177 insertions(+), 106 deletions(-)
--
2.6.1.145.gb27dacc
^ permalink raw reply [flat|nested] 19+ messages in thread* [PATCH 1/3] strbuf: make stripspace() part of strbuf 2015-10-15 12:18 [PATCH 0/3] stripspace: Implement and use --count-lines option Tobias Klauser @ 2015-10-15 12:18 ` Tobias Klauser 2015-10-15 16:42 ` Matthieu Moy ` (2 more replies) 2015-10-15 12:18 ` [PATCH 2/3] stripspace: Implement --count-lines option Tobias Klauser 2015-10-15 12:18 ` [PATCH 3/3] git rebase -i: Use newly added --count-lines option for stripspace Tobias Klauser 2 siblings, 3 replies; 19+ messages in thread From: Tobias Klauser @ 2015-10-15 12:18 UTC (permalink / raw) To: Junio C Hamano, Matthieu Moy, git Rename stripspace() to strbuf_stripspace() and move it to the strbuf module as suggested in [1]. Also switch all current users of stripspace() to the new function name and keep a temporary wrapper inline function for topic branches still using stripspace(). [1] https://git.wiki.kernel.org/index.php/SmallProjectsIdeas#make_.27stripspace.28.29.27_part_of_strbuf Signed-off-by: Tobias Klauser <tklauser@distanz.ch> --- builtin/am.c | 2 +- builtin/branch.c | 2 +- builtin/commit.c | 6 ++--- builtin/merge.c | 2 +- builtin/notes.c | 6 ++--- builtin/stripspace.c | 69 ++-------------------------------------------------- builtin/tag.c | 2 +- strbuf.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++ strbuf.h | 11 ++++++++- 9 files changed, 88 insertions(+), 78 deletions(-) diff --git a/builtin/am.c b/builtin/am.c index 4f77e07..fbe9152 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -1343,7 +1343,7 @@ static int parse_mail(struct am_state *state, const char *mail) strbuf_addstr(&msg, "\n\n"); if (strbuf_read_file(&msg, am_path(state, "msg"), 0) < 0) die_errno(_("could not read '%s'"), am_path(state, "msg")); - stripspace(&msg, 0); + strbuf_stripspace(&msg, 0); if (state->signoff) am_signoff(&msg); diff --git a/builtin/branch.c b/builtin/branch.c index 3ba4d1b..3f48746 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -794,7 +794,7 @@ static int edit_branch_description(const char *branch_name) strbuf_release(&buf); return -1; } - stripspace(&buf, 1); + strbuf_stripspace(&buf, 1); strbuf_addf(&name, "branch.%s.description", branch_name); status = git_config_set(name.buf, buf.len ? buf.buf : NULL); diff --git a/builtin/commit.c b/builtin/commit.c index 63772d0..dca09e2 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -775,7 +775,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix, s->hints = 0; if (clean_message_contents) - stripspace(&sb, 0); + strbuf_stripspace(&sb, 0); if (signoff) append_signoff(&sb, ignore_non_trailer(&sb), 0); @@ -1014,7 +1014,7 @@ static int template_untouched(struct strbuf *sb) if (!template_file || strbuf_read_file(&tmpl, template_file, 0) <= 0) return 0; - stripspace(&tmpl, cleanup_mode == CLEANUP_ALL); + strbuf_stripspace(&tmpl, cleanup_mode == CLEANUP_ALL); if (!skip_prefix(sb->buf, tmpl.buf, &start)) start = sb->buf; strbuf_release(&tmpl); @@ -1726,7 +1726,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix) wt_status_truncate_message_at_cut_line(&sb); if (cleanup_mode != CLEANUP_NONE) - stripspace(&sb, cleanup_mode == CLEANUP_ALL); + strbuf_stripspace(&sb, cleanup_mode == CLEANUP_ALL); if (template_untouched(&sb) && !allow_empty_message) { rollback_index_files(); fprintf(stderr, _("Aborting commit; you did not edit the message.\n")); diff --git a/builtin/merge.c b/builtin/merge.c index a0edaca..e6741f3 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -806,7 +806,7 @@ static void prepare_to_commit(struct commit_list *remoteheads) abort_commit(remoteheads, NULL); } read_merge_msg(&msg); - stripspace(&msg, 0 < option_edit); + strbuf_stripspace(&msg, 0 < option_edit); if (!msg.len) abort_commit(remoteheads, _("Empty commit message.")); strbuf_release(&merge_msg); diff --git a/builtin/notes.c b/builtin/notes.c index 3608c64..bb23d55 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -192,7 +192,7 @@ static void prepare_note_data(const unsigned char *object, struct note_data *d, if (launch_editor(d->edit_path, &d->buf, NULL)) { die(_("Please supply the note contents using either -m or -F option")); } - stripspace(&d->buf, 1); + strbuf_stripspace(&d->buf, 1); } } @@ -215,7 +215,7 @@ static int parse_msg_arg(const struct option *opt, const char *arg, int unset) if (d->buf.len) strbuf_addch(&d->buf, '\n'); strbuf_addstr(&d->buf, arg); - stripspace(&d->buf, 0); + strbuf_stripspace(&d->buf, 0); d->given = 1; return 0; @@ -232,7 +232,7 @@ static int parse_file_arg(const struct option *opt, const char *arg, int unset) die_errno(_("cannot read '%s'"), arg); } else if (strbuf_read_file(&d->buf, arg, 1024) < 0) die_errno(_("could not open or read '%s'"), arg); - stripspace(&d->buf, 0); + strbuf_stripspace(&d->buf, 0); d->given = 1; return 0; diff --git a/builtin/stripspace.c b/builtin/stripspace.c index 1259ed7..f677093 100644 --- a/builtin/stripspace.c +++ b/builtin/stripspace.c @@ -1,71 +1,6 @@ #include "builtin.h" #include "cache.h" - -/* - * 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 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); -} +#include "strbuf.h" static void comment_lines(struct strbuf *buf) { @@ -111,7 +46,7 @@ int cmd_stripspace(int argc, const char **argv, const char *prefix) die_errno("could not read the input"); if (mode == STRIP_SPACE) - stripspace(&buf, strip_comments); + strbuf_stripspace(&buf, strip_comments); else comment_lines(&buf); diff --git a/builtin/tag.c b/builtin/tag.c index 9e17dca..5660787 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -268,7 +268,7 @@ static void create_tag(const unsigned char *object, const char *tag, } if (opt->cleanup_mode != CLEANUP_NONE) - stripspace(buf, opt->cleanup_mode == CLEANUP_ALL); + strbuf_stripspace(buf, opt->cleanup_mode == CLEANUP_ALL); if (!opt->message_given && !buf->len) die(_("no tag message?")); diff --git a/strbuf.c b/strbuf.c index 29df55b..9583875 100644 --- a/strbuf.c +++ b/strbuf.c @@ -743,3 +743,69 @@ void strbuf_addftime(struct strbuf *sb, const char *fmt, const struct tm *tm) } strbuf_setlen(sb, sb->len + len); } + +/* + * 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); +} diff --git a/strbuf.h b/strbuf.h index aef2794..5397d91 100644 --- a/strbuf.h +++ b/strbuf.h @@ -418,7 +418,16 @@ 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. */ -extern void stripspace(struct strbuf *buf, int skip_comments); +extern void strbuf_stripspace(struct strbuf *buf, int skip_comments); + +/** + * Temporary alias until all topic branches have switched to use + * strbuf_stripspace directly. + */ +static inline void stripspace(struct strbuf *buf, int skip_comments) +{ + strbuf_stripspace(buf, skip_comments); +} static inline int strbuf_strip_suffix(struct strbuf *sb, const char *suffix) { -- 2.6.1.145.gb27dacc ^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 1/3] strbuf: make stripspace() part of strbuf 2015-10-15 12:18 ` [PATCH 1/3] strbuf: make stripspace() part of strbuf Tobias Klauser @ 2015-10-15 16:42 ` Matthieu Moy 2015-10-16 7:14 ` Tobias Klauser 2015-10-15 16:43 ` Matthieu Moy 2015-10-15 17:36 ` Junio C Hamano 2 siblings, 1 reply; 19+ messages in thread From: Matthieu Moy @ 2015-10-15 16:42 UTC (permalink / raw) To: Tobias Klauser; +Cc: Junio C Hamano, git Tobias Klauser <tklauser@distanz.ch> writes: > Also switch all current users of stripspace() to the new function name > and keep a temporary wrapper inline function for topic branches still > using stripspace(). Since you have this temporary wrapper, it would have made sense to split the patch into 1) move and rename the function, and 2) change the callsites to strbuf_stripspace. This way 2) would be absolutely trivial to review. OTOH, this patch is already easy to review, so you may consider it's OK like this. Reviewed-by: Matthieu Moy <Matthieu.Moy@imag.fr> -- Matthieu Moy http://www-verimag.imag.fr/~moy/ ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 1/3] strbuf: make stripspace() part of strbuf 2015-10-15 16:42 ` Matthieu Moy @ 2015-10-16 7:14 ` Tobias Klauser 0 siblings, 0 replies; 19+ messages in thread From: Tobias Klauser @ 2015-10-16 7:14 UTC (permalink / raw) To: Matthieu Moy; +Cc: Junio C Hamano, git On 2015-10-15 at 18:42:23 +0200, Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> wrote: > Tobias Klauser <tklauser@distanz.ch> writes: > > > Also switch all current users of stripspace() to the new function name > > and keep a temporary wrapper inline function for topic branches still > > using stripspace(). > > Since you have this temporary wrapper, it would have made sense to split > the patch into 1) move and rename the function, and 2) change the > callsites to strbuf_stripspace. This way 2) would be absolutely trivial > to review. > > OTOH, this patch is already easy to review, so you may consider it's OK > like this. Ok, in this case will keep the patch as is for v2, but with the adjusted commit message as indicated in your and Junio's review. > Reviewed-by: Matthieu Moy <Matthieu.Moy@imag.fr> Will add it to v2, thanks! ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 1/3] strbuf: make stripspace() part of strbuf 2015-10-15 12:18 ` [PATCH 1/3] strbuf: make stripspace() part of strbuf Tobias Klauser 2015-10-15 16:42 ` Matthieu Moy @ 2015-10-15 16:43 ` Matthieu Moy 2015-10-15 17:36 ` Junio C Hamano 2 siblings, 0 replies; 19+ messages in thread From: Matthieu Moy @ 2015-10-15 16:43 UTC (permalink / raw) To: Tobias Klauser; +Cc: Junio C Hamano, git Tobias Klauser <tklauser@distanz.ch> writes: > [1] https://git.wiki.kernel.org/index.php/SmallProjectsIdeas#make_.27stripspace.28.29.27_part_of_strbuf I don't think we want such references in the commit message. It does make sense in a "below ---" comment, but commit messages are here to stay forever, while the SmallProjectsIdeas entries are meant to be deleted when they are completed. (Same in other patches) -- Matthieu Moy http://www-verimag.imag.fr/~moy/ ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 1/3] strbuf: make stripspace() part of strbuf 2015-10-15 12:18 ` [PATCH 1/3] strbuf: make stripspace() part of strbuf Tobias Klauser 2015-10-15 16:42 ` Matthieu Moy 2015-10-15 16:43 ` Matthieu Moy @ 2015-10-15 17:36 ` Junio C Hamano 2015-10-16 7:09 ` Tobias Klauser 2 siblings, 1 reply; 19+ messages in thread From: Junio C Hamano @ 2015-10-15 17:36 UTC (permalink / raw) To: Tobias Klauser; +Cc: Matthieu Moy, git Tobias Klauser <tklauser@distanz.ch> writes: > Rename stripspace() to strbuf_stripspace() and move it to the strbuf > module as suggested in [1]. > > Also switch all current users of stripspace() to the new function name > and keep a temporary wrapper inline function for topic branches still > using stripspace(). > > [1] https://git.wiki.kernel.org/index.php/SmallProjectsIdeas#make_.27stripspace.28.29.27_part_of_strbuf I think Matthieu already mentioned this, but please explain why it is a good idea to do this in your own words here, without forcing readers to go to other places to find out. Giving credit to an external page for giving you an inspiration to do something is good, but the proposed log message needs to justify itself. In other words, when you are challenged to defend this change, you are not allowed to say "SmallProjectIdeas page said it is a good thing to do. I just did it without questioning it." ;-) Instead you are expected to justify it yourself. > Signed-off-by: Tobias Klauser <tklauser@distanz.ch> > --- A good rule of thumb to see if it is a good time to do this kind of change is to do this: $ git log -p maint..pu | grep stripspace which shows only one mention in a context, so this change may cause textual conflict with something else somewhere nearby but won't hurt other topics in flight. The patch itself looks OK. Thanks. > builtin/am.c | 2 +- > builtin/branch.c | 2 +- > builtin/commit.c | 6 ++--- > builtin/merge.c | 2 +- > builtin/notes.c | 6 ++--- > builtin/stripspace.c | 69 ++-------------------------------------------------- > builtin/tag.c | 2 +- > strbuf.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++ > strbuf.h | 11 ++++++++- > 9 files changed, 88 insertions(+), 78 deletions(-) > > diff --git a/builtin/am.c b/builtin/am.c > index 4f77e07..fbe9152 100644 > --- a/builtin/am.c > +++ b/builtin/am.c > @@ -1343,7 +1343,7 @@ static int parse_mail(struct am_state *state, const char *mail) > strbuf_addstr(&msg, "\n\n"); > if (strbuf_read_file(&msg, am_path(state, "msg"), 0) < 0) > die_errno(_("could not read '%s'"), am_path(state, "msg")); > - stripspace(&msg, 0); > + strbuf_stripspace(&msg, 0); > > if (state->signoff) > am_signoff(&msg); > diff --git a/builtin/branch.c b/builtin/branch.c > index 3ba4d1b..3f48746 100644 > --- a/builtin/branch.c > +++ b/builtin/branch.c > @@ -794,7 +794,7 @@ static int edit_branch_description(const char *branch_name) > strbuf_release(&buf); > return -1; > } > - stripspace(&buf, 1); > + strbuf_stripspace(&buf, 1); > > strbuf_addf(&name, "branch.%s.description", branch_name); > status = git_config_set(name.buf, buf.len ? buf.buf : NULL); > diff --git a/builtin/commit.c b/builtin/commit.c > index 63772d0..dca09e2 100644 > --- a/builtin/commit.c > +++ b/builtin/commit.c > @@ -775,7 +775,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix, > s->hints = 0; > > if (clean_message_contents) > - stripspace(&sb, 0); > + strbuf_stripspace(&sb, 0); > > if (signoff) > append_signoff(&sb, ignore_non_trailer(&sb), 0); > @@ -1014,7 +1014,7 @@ static int template_untouched(struct strbuf *sb) > if (!template_file || strbuf_read_file(&tmpl, template_file, 0) <= 0) > return 0; > > - stripspace(&tmpl, cleanup_mode == CLEANUP_ALL); > + strbuf_stripspace(&tmpl, cleanup_mode == CLEANUP_ALL); > if (!skip_prefix(sb->buf, tmpl.buf, &start)) > start = sb->buf; > strbuf_release(&tmpl); > @@ -1726,7 +1726,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix) > wt_status_truncate_message_at_cut_line(&sb); > > if (cleanup_mode != CLEANUP_NONE) > - stripspace(&sb, cleanup_mode == CLEANUP_ALL); > + strbuf_stripspace(&sb, cleanup_mode == CLEANUP_ALL); > if (template_untouched(&sb) && !allow_empty_message) { > rollback_index_files(); > fprintf(stderr, _("Aborting commit; you did not edit the message.\n")); > diff --git a/builtin/merge.c b/builtin/merge.c > index a0edaca..e6741f3 100644 > --- a/builtin/merge.c > +++ b/builtin/merge.c > @@ -806,7 +806,7 @@ static void prepare_to_commit(struct commit_list *remoteheads) > abort_commit(remoteheads, NULL); > } > read_merge_msg(&msg); > - stripspace(&msg, 0 < option_edit); > + strbuf_stripspace(&msg, 0 < option_edit); > if (!msg.len) > abort_commit(remoteheads, _("Empty commit message.")); > strbuf_release(&merge_msg); > diff --git a/builtin/notes.c b/builtin/notes.c > index 3608c64..bb23d55 100644 > --- a/builtin/notes.c > +++ b/builtin/notes.c > @@ -192,7 +192,7 @@ static void prepare_note_data(const unsigned char *object, struct note_data *d, > if (launch_editor(d->edit_path, &d->buf, NULL)) { > die(_("Please supply the note contents using either -m or -F option")); > } > - stripspace(&d->buf, 1); > + strbuf_stripspace(&d->buf, 1); > } > } > > @@ -215,7 +215,7 @@ static int parse_msg_arg(const struct option *opt, const char *arg, int unset) > if (d->buf.len) > strbuf_addch(&d->buf, '\n'); > strbuf_addstr(&d->buf, arg); > - stripspace(&d->buf, 0); > + strbuf_stripspace(&d->buf, 0); > > d->given = 1; > return 0; > @@ -232,7 +232,7 @@ static int parse_file_arg(const struct option *opt, const char *arg, int unset) > die_errno(_("cannot read '%s'"), arg); > } else if (strbuf_read_file(&d->buf, arg, 1024) < 0) > die_errno(_("could not open or read '%s'"), arg); > - stripspace(&d->buf, 0); > + strbuf_stripspace(&d->buf, 0); > > d->given = 1; > return 0; > diff --git a/builtin/stripspace.c b/builtin/stripspace.c > index 1259ed7..f677093 100644 > --- a/builtin/stripspace.c > +++ b/builtin/stripspace.c > @@ -1,71 +1,6 @@ > #include "builtin.h" > #include "cache.h" > - > -/* > - * 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 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); > -} > +#include "strbuf.h" > > static void comment_lines(struct strbuf *buf) > { > @@ -111,7 +46,7 @@ int cmd_stripspace(int argc, const char **argv, const char *prefix) > die_errno("could not read the input"); > > if (mode == STRIP_SPACE) > - stripspace(&buf, strip_comments); > + strbuf_stripspace(&buf, strip_comments); > else > comment_lines(&buf); > > diff --git a/builtin/tag.c b/builtin/tag.c > index 9e17dca..5660787 100644 > --- a/builtin/tag.c > +++ b/builtin/tag.c > @@ -268,7 +268,7 @@ static void create_tag(const unsigned char *object, const char *tag, > } > > if (opt->cleanup_mode != CLEANUP_NONE) > - stripspace(buf, opt->cleanup_mode == CLEANUP_ALL); > + strbuf_stripspace(buf, opt->cleanup_mode == CLEANUP_ALL); > > if (!opt->message_given && !buf->len) > die(_("no tag message?")); > diff --git a/strbuf.c b/strbuf.c > index 29df55b..9583875 100644 > --- a/strbuf.c > +++ b/strbuf.c > @@ -743,3 +743,69 @@ void strbuf_addftime(struct strbuf *sb, const char *fmt, const struct tm *tm) > } > strbuf_setlen(sb, sb->len + len); > } > + > +/* > + * 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); > +} > diff --git a/strbuf.h b/strbuf.h > index aef2794..5397d91 100644 > --- a/strbuf.h > +++ b/strbuf.h > @@ -418,7 +418,16 @@ 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. > */ > -extern void stripspace(struct strbuf *buf, int skip_comments); > +extern void strbuf_stripspace(struct strbuf *buf, int skip_comments); > + > +/** > + * Temporary alias until all topic branches have switched to use > + * strbuf_stripspace directly. > + */ > +static inline void stripspace(struct strbuf *buf, int skip_comments) > +{ > + strbuf_stripspace(buf, skip_comments); > +} > > static inline int strbuf_strip_suffix(struct strbuf *sb, const char *suffix) > { ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 1/3] strbuf: make stripspace() part of strbuf 2015-10-15 17:36 ` Junio C Hamano @ 2015-10-16 7:09 ` Tobias Klauser 0 siblings, 0 replies; 19+ messages in thread From: Tobias Klauser @ 2015-10-16 7:09 UTC (permalink / raw) To: Junio C Hamano; +Cc: Matthieu Moy, git Thanks for the review. On 2015-10-15 at 19:36:17 +0200, Junio C Hamano <gitster@pobox.com> wrote: > Tobias Klauser <tklauser@distanz.ch> writes: > > > Rename stripspace() to strbuf_stripspace() and move it to the strbuf > > module as suggested in [1]. > > > > Also switch all current users of stripspace() to the new function name > > and keep a temporary wrapper inline function for topic branches still > > using stripspace(). > > > > [1] https://git.wiki.kernel.org/index.php/SmallProjectsIdeas#make_.27stripspace.28.29.27_part_of_strbuf > > I think Matthieu already mentioned this, but please explain why it > is a good idea to do this in your own words here, without forcing > readers to go to other places to find out. Giving credit to an > external page for giving you an inspiration to do something is good, > but the proposed log message needs to justify itself. In other > words, when you are challenged to defend this change, you are not > allowed to say "SmallProjectIdeas page said it is a good thing to > do. I just did it without questioning it." ;-) Instead you are > expected to justify it yourself. Yes, makes sense. I'll adjust the commit message for v2 to justify the change for itself and move the link below --- as Matthieu suggested. > > Signed-off-by: Tobias Klauser <tklauser@distanz.ch> > > --- > > A good rule of thumb to see if it is a good time to do this kind of > change is to do this: > > $ git log -p maint..pu | grep stripspace > > which shows only one mention in a context, so this change may cause > textual conflict with something else somewhere nearby but won't hurt > other topics in flight. Ok, thanks for the hint. I'll check again before resubmitting v2. Thanks ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 2/3] stripspace: Implement --count-lines option 2015-10-15 12:18 [PATCH 0/3] stripspace: Implement and use --count-lines option Tobias Klauser 2015-10-15 12:18 ` [PATCH 1/3] strbuf: make stripspace() part of strbuf Tobias Klauser @ 2015-10-15 12:18 ` Tobias Klauser 2015-10-15 16:52 ` Matthieu Moy ` (2 more replies) 2015-10-15 12:18 ` [PATCH 3/3] git rebase -i: Use newly added --count-lines option for stripspace Tobias Klauser 2 siblings, 3 replies; 19+ messages in thread From: Tobias Klauser @ 2015-10-15 12:18 UTC (permalink / raw) To: Junio C Hamano, Matthieu Moy, git 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@distanz.ch> --- 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 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [PATCH 2/3] stripspace: Implement --count-lines option 2015-10-15 12:18 ` [PATCH 2/3] stripspace: Implement --count-lines option Tobias Klauser @ 2015-10-15 16:52 ` Matthieu Moy 2015-10-16 7:21 ` Tobias Klauser 2015-10-16 8:40 ` Tobias Klauser 2015-10-15 17:58 ` Junio C Hamano 2015-10-15 19:21 ` Matthieu Moy 2 siblings, 2 replies; 19+ messages in thread From: Matthieu Moy @ 2015-10-15 16:52 UTC (permalink / raw) To: Tobias Klauser; +Cc: Junio C Hamano, git Tobias Klauser <tklauser@distanz.ch> writes: > --- 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 I'm not sure it's a good idea to introduce a one-letter shortcut (-C). In scripts, --count-lines is self-explanatory hence more readable than -C (which is even more confusing since "git -C foo stripspace" and "git stripspace -C" have totally different meanings. Outside scripts, I'm not sure the command would be useful. I'd rather avoid polluting the one-letter-option namespace. > +Use 'git stripspace --count-lines' to obtain: > + > +--------- > +|5$ > +--------- In the examples above, I read the | as part of the input (unlike $ which is used only to show the end of line). So the | should not be here. I don't think you need the $ either, the --count-lines option is no longer about trailing whitespaces. > +static const char * const usage_msg[] = { Stick the * to usage_msg please. No time to review the rest for now sorry. -- Matthieu Moy http://www-verimag.imag.fr/~moy/ ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 2/3] stripspace: Implement --count-lines option 2015-10-15 16:52 ` Matthieu Moy @ 2015-10-16 7:21 ` Tobias Klauser 2015-10-16 8:40 ` Tobias Klauser 1 sibling, 0 replies; 19+ messages in thread From: Tobias Klauser @ 2015-10-16 7:21 UTC (permalink / raw) To: Matthieu Moy; +Cc: Junio C Hamano, git On 2015-10-15 at 18:52:54 +0200, Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> wrote: > Tobias Klauser <tklauser@distanz.ch> writes: > > > --- 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 > > I'm not sure it's a good idea to introduce a one-letter shortcut (-C). > In scripts, --count-lines is self-explanatory hence more readable than > -C (which is even more confusing since "git -C foo stripspace" and "git > stripspace -C" have totally different meanings. Outside scripts, I'm not > sure the command would be useful. I'd rather avoid polluting the > one-letter-option namespace. Ok, I'll drop the -C. Didn't consider the `git -C stripspace' case, so that's definitely unwanted. > > +Use 'git stripspace --count-lines' to obtain: > > + > > +--------- > > +|5$ > > +--------- > > In the examples above, I read the | as part of the input (unlike $ which > is used only to show the end of line). So the | should not be here. I > don't think you need the $ either, the --count-lines option is no longer > about trailing whitespaces. Will drop both | and $. Seems I didn't check the output careful enough, both don't make sense for this option. > > +static const char * const usage_msg[] = { > > Stick the * to usage_msg please. Will change in v2. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 2/3] stripspace: Implement --count-lines option 2015-10-15 16:52 ` Matthieu Moy 2015-10-16 7:21 ` Tobias Klauser @ 2015-10-16 8:40 ` Tobias Klauser 2015-10-16 8:59 ` Matthieu Moy 1 sibling, 1 reply; 19+ messages in thread From: Tobias Klauser @ 2015-10-16 8:40 UTC (permalink / raw) To: Matthieu Moy; +Cc: Junio C Hamano, git On 2015-10-15 at 18:52:54 +0200, Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> wrote: > Tobias Klauser <tklauser@distanz.ch> writes: > > +static const char * const usage_msg[] = { > > Stick the * to usage_msg please. Just noticed while looking at how other sub-commands define this, the vast majority use "const char * const" and not "const char const *". Also it would change the meaning. The following wouldn't produce a compiler warning: static const char const *usage_msg[] = { ... }; ... usage_msg[0] = "Foobar" while static const char * const usage_msg[] = { ... }; ... usage_msg[0] = "Foobar" would produce one: builtin/stripspace.c:36:2: error: assignment of read-only location ‘usage_msg[0]’ Even though I don't expect anyone to modify usage_msg at runtime I think it'd be better to stick with the current version. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 2/3] stripspace: Implement --count-lines option 2015-10-16 8:40 ` Tobias Klauser @ 2015-10-16 8:59 ` Matthieu Moy 0 siblings, 0 replies; 19+ messages in thread From: Matthieu Moy @ 2015-10-16 8:59 UTC (permalink / raw) To: Tobias Klauser; +Cc: Junio C Hamano, git Tobias Klauser <tklauser@distanz.ch> writes: > On 2015-10-15 at 18:52:54 +0200, Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> wrote: >> Tobias Klauser <tklauser@distanz.ch> writes: >> > +static const char * const usage_msg[] = { >> >> Stick the * to usage_msg please. > > Just noticed while looking at how other sub-commands define this, the vast > majority use "const char * const" and not "const char const *". Oops, I read your code too quickly. We stick the * to variable names when it follows the star, but I didn't see the "const", sorry. -- Matthieu Moy http://www-verimag.imag.fr/~moy/ ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 2/3] stripspace: Implement --count-lines option 2015-10-15 12:18 ` [PATCH 2/3] stripspace: Implement --count-lines option Tobias Klauser 2015-10-15 16:52 ` Matthieu Moy @ 2015-10-15 17:58 ` Junio C Hamano 2015-10-16 7:51 ` Tobias Klauser 2015-10-15 19:21 ` Matthieu Moy 2 siblings, 1 reply; 19+ messages in thread From: Junio C Hamano @ 2015-10-15 17:58 UTC (permalink / raw) To: Tobias Klauser; +Cc: Matthieu Moy, git Tobias Klauser <tklauser@distanz.ch> writes: > 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'. I agree with Matthieu that squatting on a short-and-sweet -C is unwanted here. > 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() > + }; I think -s and -c are incompatible, so OPT_CMDMODE() might be a better fit for them if you are going to switch the command line parser to use parse-options. Which makes me strongly suspect that this should be done in at least two separate steps. (1) Use parse-options to parse command line without adding the counting at all, followed by (2) Add counting. > + 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); > + } So this is your output code, which gives only the number of lines without the cleaned up result. > @@ -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++; > } > } I cannot say that the above is one of the better possible implementations of this feature I would think of. (1) If this is performance sensitive, then you do not want to do memmove() etc. to actually touch the contents of the *sb and only increment lines++, because you are not going to show that in the output anyway. (2) If this feature is not performance sensitive, then the best implementation would be not to touch strbuf_stripspace() at all to realize this change, and count the number of '\n' in the cmd_stripspace() just before you use printf("%d\n", lines). That is best from maintainability's point-of-view, because it makes it infinitely less error-prone for future changes of strbuf_stripspace() to forget incrementing lines++ when it adds a newline to the output. (3) If you are going to still munge *sb, even if you are not going to show it at the end, perhaps because that would make it easier to keep track of where the code is scanning to find when you need to increment lines++, then at least the patch should devise a mechanism to make it less likely that the future changes to strbuf_stripspace() would make 'lines' and the number of '\n' in the *sb out-of-sync (hint: perhaps a macro called APPEND_LF(sb, line) or something). It is easy to append '\n' to sb->buf without incrementing lines++ as the code stands with this patch applied---the patch makes the code less maintainable. My gut feeling is that you should do (2), which is the cleanest from the maintainability's point-of-view. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 2/3] stripspace: Implement --count-lines option 2015-10-15 17:58 ` Junio C Hamano @ 2015-10-16 7:51 ` Tobias Klauser 2015-10-16 17:35 ` Junio C Hamano 0 siblings, 1 reply; 19+ messages in thread From: Tobias Klauser @ 2015-10-16 7:51 UTC (permalink / raw) To: Junio C Hamano; +Cc: Matthieu Moy, git On 2015-10-15 at 19:58:26 +0200, Junio C Hamano <gitster@pobox.com> wrote: > Tobias Klauser <tklauser@distanz.ch> writes: > > > 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'. > > I agree with Matthieu that squatting on a short-and-sweet -C is > unwanted here. Will drop it in v2. > > 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() > > + }; > > I think -s and -c are incompatible, so OPT_CMDMODE() might be a > better fit for them if you are going to switch the command line > parser to use parse-options. Ok, will change to OPT_CMDMODE() > Which makes me strongly suspect that this should be done in at least > two separate steps. (1) Use parse-options to parse command line > without adding the counting at all, followed by (2) Add counting. Ok, will split the patch as you suggest for v2 (or more if it makes it easier to review). > > + 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); > > + } > > So this is your output code, which gives only the number of lines > without the cleaned up result. This should better be a simple printf("%zu\n", lines) I guess? > > @@ -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++; > > } > > } > > I cannot say that the above is one of the better possible > implementations of this feature I would think of. > > (1) If this is performance sensitive, then you do not want to do > memmove() etc. to actually touch the contents of the *sb and > only increment lines++, because you are not going to show that > in the output anyway. > > (2) If this feature is not performance sensitive, then the best > implementation would be not to touch strbuf_stripspace() at all > to realize this change, and count the number of '\n' in the > cmd_stripspace() just before you use printf("%d\n", lines). > That is best from maintainability's point-of-view, because it > makes it infinitely less error-prone for future changes of > strbuf_stripspace() to forget incrementing lines++ when it adds > a newline to the output. > > (3) If you are going to still munge *sb, even if you are not going > to show it at the end, perhaps because that would make it > easier to keep track of where the code is scanning to find when > you need to increment lines++, then at least the patch should > devise a mechanism to make it less likely that the future > changes to strbuf_stripspace() would make 'lines' and the > number of '\n' in the *sb out-of-sync (hint: perhaps a macro > called APPEND_LF(sb, line) or something). It is easy to append > '\n' to sb->buf without incrementing lines++ as the code stands > with this patch applied---the patch makes the code less > maintainable. > > My gut feeling is that you should do (2), which is the cleanest from > the maintainability's point-of-view. Thank you for outlining and assessing these possible implementations. I agree that my suggested implementation is probably the most naïve one :) and think that (2) would less intrusive and better to maintain. Will change the patch accordingly. > ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 2/3] stripspace: Implement --count-lines option 2015-10-16 7:51 ` Tobias Klauser @ 2015-10-16 17:35 ` Junio C Hamano 2015-10-17 10:44 ` Tobias Klauser 0 siblings, 1 reply; 19+ messages in thread From: Junio C Hamano @ 2015-10-16 17:35 UTC (permalink / raw) To: Tobias Klauser; +Cc: Matthieu Moy, git Tobias Klauser <tklauser@distanz.ch> writes: >> So this is your output code, which gives only the number of lines >> without the cleaned up result. > > This should better be a simple printf("%zu\n", lines) I guess? I think we actively avoid using %z conversion that is only C99. If you really want to, you could count in size_t and use %lu with appropriate casting, which I think is what we do in the rest of the codebase. For this one, I think it is sufficient to just count in int and print as int with %d, though. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 2/3] stripspace: Implement --count-lines option 2015-10-16 17:35 ` Junio C Hamano @ 2015-10-17 10:44 ` Tobias Klauser 0 siblings, 0 replies; 19+ messages in thread From: Tobias Klauser @ 2015-10-17 10:44 UTC (permalink / raw) To: Junio C Hamano; +Cc: Matthieu Moy, git On 2015-10-16 at 19:35:49 +0200, Junio C Hamano <gitster@pobox.com> wrote: > Tobias Klauser <tklauser@distanz.ch> writes: > > >> So this is your output code, which gives only the number of lines > >> without the cleaned up result. > > > > This should better be a simple printf("%zu\n", lines) I guess? > > I think we actively avoid using %z conversion that is only C99. > > If you really want to, you could count in size_t and use %lu with > appropriate casting, which I think is what we do in the rest of the > codebase. > > For this one, I think it is sufficient to just count in int and > print as int with %d, though. Ok, will use an int to count and printf("%d\n"). ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 2/3] stripspace: Implement --count-lines option 2015-10-15 12:18 ` [PATCH 2/3] stripspace: Implement --count-lines option Tobias Klauser 2015-10-15 16:52 ` Matthieu Moy 2015-10-15 17:58 ` Junio C Hamano @ 2015-10-15 19:21 ` Matthieu Moy 2015-10-16 7:54 ` Tobias Klauser 2 siblings, 1 reply; 19+ messages in thread From: Matthieu Moy @ 2015-10-15 19:21 UTC (permalink / raw) To: Tobias Klauser; +Cc: Junio C Hamano, git Tobias Klauser <tklauser@distanz.ch> writes: > + * comments are considered contents to be removed or not. Returns the > + * number of lines in the resulting buffer. We write comments at imperative tone, hence "Return", not "Returns". Other than that, I agree with Junio: * A preparatory patch introducing parse-options would make the actual patch much easier to review. * Just running strbuf_stripspace and counting the number of lines in the result is much simpler. We use stripspace only on user-provided input which are never really big so maintainability is more important than performance. Cheers, -- Matthieu Moy http://www-verimag.imag.fr/~moy/ ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH 2/3] stripspace: Implement --count-lines option 2015-10-15 19:21 ` Matthieu Moy @ 2015-10-16 7:54 ` Tobias Klauser 0 siblings, 0 replies; 19+ messages in thread From: Tobias Klauser @ 2015-10-16 7:54 UTC (permalink / raw) To: Matthieu Moy; +Cc: Junio C Hamano, git On 2015-10-15 at 21:21:53 +0200, Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> wrote: > Tobias Klauser <tklauser@distanz.ch> writes: > > > + * comments are considered contents to be removed or not. Returns the > > + * number of lines in the resulting buffer. > > We write comments at imperative tone, hence "Return", not "Returns". The other comments in strbuf.h used "Returns", so I went for it for consistency reasons. But the comment will be obsolete anyhow, as strbuf_stripspace() will not be changed and the functionality implemented in cmd_stripspace() as Junio suggested. > Other than that, I agree with Junio: > > * A preparatory patch introducing parse-options would make the actual > patch much easier to review. Will do. > > * Just running strbuf_stripspace and counting the number of lines in the > result is much simpler. We use stripspace only on user-provided input > which are never really big so maintainability is more important than > performance. Ditto. Thanks ^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH 3/3] git rebase -i: Use newly added --count-lines option for stripspace 2015-10-15 12:18 [PATCH 0/3] stripspace: Implement and use --count-lines option Tobias Klauser 2015-10-15 12:18 ` [PATCH 1/3] strbuf: make stripspace() part of strbuf Tobias Klauser 2015-10-15 12:18 ` [PATCH 2/3] stripspace: Implement --count-lines option Tobias Klauser @ 2015-10-15 12:18 ` Tobias Klauser 2 siblings, 0 replies; 19+ messages in thread From: Tobias Klauser @ 2015-10-15 12:18 UTC (permalink / raw) To: Junio C Hamano, Matthieu Moy, git Use the newly added --count-lines option for 'git stripspace' to count lines instead of piping the entire output to 'wc -l'. Signed-off-by: Tobias Klauser <tklauser@distanz.ch> --- git-rebase--interactive.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index f01637b..c40ca90 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -120,9 +120,9 @@ mark_action_done () { sed -e 1q < "$todo" >> "$done" sed -e 1d < "$todo" >> "$todo".new mv -f "$todo".new "$todo" - new_count=$(git stripspace --strip-comments <"$done" | wc -l) + new_count=$(git stripspace --strip-comments --count-lines <"$done") echo $new_count >"$msgnum" - total=$(($new_count + $(git stripspace --strip-comments <"$todo" | wc -l))) + total=$(($new_count + $(git stripspace --strip-comments --count-lines <"$todo"))) echo $total >"$end" if test "$last_count" != "$new_count" then @@ -1247,7 +1247,7 @@ test -s "$todo" || echo noop >> "$todo" test -n "$autosquash" && rearrange_squash "$todo" test -n "$cmd" && add_exec_commands "$todo" -todocount=$(git stripspace --strip-comments <"$todo" | wc -l) +todocount=$(git stripspace --strip-comments --count-lines <"$todo") todocount=${todocount##* } cat >>"$todo" <<EOF -- 2.6.1.145.gb27dacc ^ permalink raw reply related [flat|nested] 19+ messages in thread
end of thread, other threads:[~2015-10-17 10:44 UTC | newest] Thread overview: 19+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2015-10-15 12:18 [PATCH 0/3] stripspace: Implement and use --count-lines option Tobias Klauser 2015-10-15 12:18 ` [PATCH 1/3] strbuf: make stripspace() part of strbuf Tobias Klauser 2015-10-15 16:42 ` Matthieu Moy 2015-10-16 7:14 ` Tobias Klauser 2015-10-15 16:43 ` Matthieu Moy 2015-10-15 17:36 ` Junio C Hamano 2015-10-16 7:09 ` Tobias Klauser 2015-10-15 12:18 ` [PATCH 2/3] stripspace: Implement --count-lines option Tobias Klauser 2015-10-15 16:52 ` Matthieu Moy 2015-10-16 7:21 ` Tobias Klauser 2015-10-16 8:40 ` Tobias Klauser 2015-10-16 8:59 ` Matthieu Moy 2015-10-15 17:58 ` Junio C Hamano 2015-10-16 7:51 ` Tobias Klauser 2015-10-16 17:35 ` Junio C Hamano 2015-10-17 10:44 ` Tobias Klauser 2015-10-15 19:21 ` Matthieu Moy 2015-10-16 7:54 ` Tobias Klauser 2015-10-15 12:18 ` [PATCH 3/3] git rebase -i: Use newly added --count-lines option for stripspace Tobias Klauser
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).