Merge branch 'jc/quote'
[git] / builtin-stripspace.c
1 #include "builtin.h"
2 #include "cache.h"
3
4 /*
5  * Remove trailing spaces from a line.
6  *
7  * If the line ends with newline, it will be removed too.
8  * Returns the new length of the string.
9  */
10 static int cleanup(char *line, int len)
11 {
12         if (len) {
13                 if (line[len - 1] == '\n')
14                         len--;
15
16                 while (len) {
17                         unsigned char c = line[len - 1];
18                         if (!isspace(c))
19                                 break;
20                         len--;
21                 }
22                 line[len] = 0;
23         }
24         return len;
25 }
26
27 /*
28  * Remove empty lines from the beginning and end
29  * and also trailing spaces from every line.
30  *
31  * Turn multiple consecutive empty lines between paragraphs
32  * into just one empty line.
33  *
34  * If the input has only empty lines and spaces,
35  * no output will be produced.
36  *
37  * Enable skip_comments to skip every line starting with "#".
38  */
39 void stripspace(FILE *in, FILE *out, int skip_comments)
40 {
41         int empties = -1;
42         int alloc = 1024;
43         char *line = xmalloc(alloc);
44
45         while (fgets(line, alloc, in)) {
46                 int len = strlen(line);
47
48                 while (len == alloc - 1 && line[len - 1] != '\n') {
49                         alloc = alloc_nr(alloc);
50                         line = xrealloc(line, alloc);
51                         fgets(line + len, alloc - len, in);
52                         len += strlen(line + len);
53                 }
54
55                 if (skip_comments && line[0] == '#')
56                         continue;
57                 len = cleanup(line, len);
58
59                 /* Not just an empty line? */
60                 if (len) {
61                         if (empties > 0)
62                                 fputc('\n', out);
63                         empties = 0;
64                         fputs(line, out);
65                         fputc('\n', out);
66                         continue;
67                 }
68                 if (empties < 0)
69                         continue;
70                 empties++;
71         }
72         free(line);
73 }
74
75 int cmd_stripspace(int argc, const char **argv, const char *prefix)
76 {
77         stripspace(stdin, stdout, 0);
78         return 0;
79 }