33e8fc8740
The synopsys text and the usage string of subcommands that read list of things from the standard input are often shown like this: git gostak [--distim] < <list-of-doshes> This is problematic in a number of ways: * The way to use these commands is more often to feed them the output from another command, not feed them from a file. * Manual pages outside Git, commands that operate on the data read from the standard input, e.g "sort", "grep", "sed", etc., are not described with such a "< redirection-from-file" in their synopsys text. Our doing so introduces inconsistency. * We do not insist on where the output should go, by saying git gostak [--distim] < <list-of-doshes> > <output> * As it is our convention to enclose placeholders inside <braket>, the redirection operator followed by a placeholder filename becomes very hard to read, both in the documentation and in the help text. Let's clean them all up, after making sure that the documentation clearly describes the modes that take information from the standard input and what kind of things are expected on the input. [jc: stole example for fmt-merge-msg from Jonathan] Helped-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
122 lines
2.6 KiB
C
122 lines
2.6 KiB
C
#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);
|
|
}
|
|
|
|
static void comment_lines(struct strbuf *buf)
|
|
{
|
|
char *msg;
|
|
size_t len;
|
|
|
|
msg = strbuf_detach(buf, &len);
|
|
strbuf_add_commented_lines(buf, msg, len);
|
|
free(msg);
|
|
}
|
|
|
|
static const char *usage_msg = "\n"
|
|
" git stripspace [-s | --strip-comments]\n"
|
|
" git stripspace [-c | --comment-lines]";
|
|
|
|
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;
|
|
}
|
|
|
|
if (mode == INVAL)
|
|
usage(usage_msg);
|
|
|
|
if (strip_comments || mode == COMMENT_LINES)
|
|
git_config(git_default_config, NULL);
|
|
|
|
if (strbuf_read(&buf, 0, 1024) < 0)
|
|
die_errno("could not read the input");
|
|
|
|
if (mode == STRIP_SPACE)
|
|
stripspace(&buf, strip_comments);
|
|
else
|
|
comment_lines(&buf);
|
|
|
|
write_or_die(1, buf.buf, buf.len);
|
|
strbuf_release(&buf);
|
|
return 0;
|
|
}
|