Rewrite convert_to_{git,working_tree} to use strbuf's.
[git/dscho.git] / builtin-stripspace.c
blobc4cf2f05ca13adeb340b3274b0f029c7734af834
1 #include "builtin.h"
2 #include "cache.h"
3 #include "strbuf.h"
5 /*
6 * Returns the length of a line, without trailing spaces.
8 * If the line ends with newline, it will be removed too.
9 */
10 static size_t cleanup(char *line, size_t len)
12 if (len) {
13 if (line[len - 1] == '\n')
14 len--;
16 while (len) {
17 unsigned char c = line[len - 1];
18 if (!isspace(c))
19 break;
20 len--;
23 return len;
27 * Remove empty lines from the beginning and end
28 * and also trailing spaces from every line.
30 * Note that the buffer will not be NUL-terminated.
32 * Turn multiple consecutive empty lines between paragraphs
33 * into just one empty line.
35 * If the input has only empty lines and spaces,
36 * no output will be produced.
38 * If last line has a newline at the end, it will be removed.
40 * Enable skip_comments to skip every line starting with "#".
42 size_t stripspace(char *buffer, size_t length, int skip_comments)
44 int empties = -1;
45 size_t i, j, len, newlen;
46 char *eol;
48 for (i = j = 0; i < length; i += len, j += newlen) {
49 eol = memchr(buffer + i, '\n', length - i);
50 len = eol ? eol - (buffer + i) + 1 : length - i;
52 if (skip_comments && len && buffer[i] == '#') {
53 newlen = 0;
54 continue;
56 newlen = cleanup(buffer + i, len);
58 /* Not just an empty line? */
59 if (newlen) {
60 if (empties != -1)
61 buffer[j++] = '\n';
62 if (empties > 0)
63 buffer[j++] = '\n';
64 empties = 0;
65 memmove(buffer + j, buffer + i, newlen);
66 continue;
68 if (empties < 0)
69 continue;
70 empties++;
73 return j;
76 int cmd_stripspace(int argc, const char **argv, const char *prefix)
78 struct strbuf buf;
79 int strip_comments = 0;
81 if (argc > 1 && (!strcmp(argv[1], "-s") ||
82 !strcmp(argv[1], "--strip-comments")))
83 strip_comments = 1;
85 strbuf_init(&buf, 0);
86 if (strbuf_read(&buf, 0, 1024) < 0)
87 die("could not read the input");
89 strbuf_setlen(&buf, stripspace(buf.buf, buf.len, strip_comments));
90 if (buf.len)
91 strbuf_addch(&buf, '\n');
93 write_or_die(1, buf.buf, buf.len);
94 strbuf_release(&buf);
95 return 0;