]>
Commit | Line | Data |
---|---|---|
7499c996 | 1 | #include "builtin.h" |
9690c118 | 2 | #include "cache.h" |
a3e870f2 LT |
3 | |
4 | /* | |
975e0daf | 5 | * Returns the length of a line, without trailing spaces. |
a3e870f2 | 6 | * |
9690c118 | 7 | * If the line ends with newline, it will be removed too. |
a3e870f2 | 8 | */ |
975e0daf | 9 | static size_t cleanup(char *line, size_t len) |
a3e870f2 | 10 | { |
9690c118 CR |
11 | if (len) { |
12 | if (line[len - 1] == '\n') | |
13 | len--; | |
a3e870f2 | 14 | |
9690c118 CR |
15 | while (len) { |
16 | unsigned char c = line[len - 1]; | |
a3e870f2 LT |
17 | if (!isspace(c)) |
18 | break; | |
a3e870f2 | 19 | len--; |
9690c118 | 20 | } |
a3e870f2 | 21 | } |
9690c118 | 22 | return len; |
a3e870f2 LT |
23 | } |
24 | ||
9690c118 CR |
25 | /* |
26 | * Remove empty lines from the beginning and end | |
27 | * and also trailing spaces from every line. | |
28 | * | |
975e0daf CR |
29 | * Note that the buffer will not be NUL-terminated. |
30 | * | |
9690c118 CR |
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 | * | |
975e0daf CR |
37 | * If last line has a newline at the end, it will be removed. |
38 | * | |
9690c118 CR |
39 | * Enable skip_comments to skip every line starting with "#". |
40 | */ | |
975e0daf | 41 | size_t stripspace(char *buffer, size_t length, int skip_comments) |
a3e870f2 LT |
42 | { |
43 | int empties = -1; | |
975e0daf CR |
44 | size_t i, j, len, newlen; |
45 | char *eol; | |
9690c118 | 46 | |
975e0daf CR |
47 | for (i = j = 0; i < length; i += len, j += newlen) { |
48 | eol = memchr(buffer + i, '\n', length - i); | |
49 | len = eol ? eol - (buffer + i) + 1 : length - i; | |
a3e870f2 | 50 | |
975e0daf CR |
51 | if (skip_comments && len && buffer[i] == '#') { |
52 | newlen = 0; | |
9690c118 | 53 | continue; |
975e0daf CR |
54 | } |
55 | newlen = cleanup(buffer + i, len); | |
a3e870f2 LT |
56 | |
57 | /* Not just an empty line? */ | |
975e0daf CR |
58 | if (newlen) { |
59 | if (empties != -1) | |
60 | buffer[j++] = '\n'; | |
a3e870f2 | 61 | if (empties > 0) |
975e0daf | 62 | buffer[j++] = '\n'; |
a3e870f2 | 63 | empties = 0; |
975e0daf | 64 | memmove(buffer + j, buffer + i, newlen); |
a3e870f2 LT |
65 | continue; |
66 | } | |
67 | if (empties < 0) | |
68 | continue; | |
69 | empties++; | |
70 | } | |
975e0daf CR |
71 | |
72 | return j; | |
7499c996 LS |
73 | } |
74 | ||
a633fca0 | 75 | int cmd_stripspace(int argc, const char **argv, const char *prefix) |
7499c996 | 76 | { |
975e0daf CR |
77 | char *buffer; |
78 | unsigned long size; | |
f653aee5 JS |
79 | int strip_comments = 0; |
80 | ||
81 | if (argc > 1 && (!strcmp(argv[1], "-s") || | |
82 | !strcmp(argv[1], "--strip-comments"))) | |
83 | strip_comments = 1; | |
975e0daf CR |
84 | |
85 | size = 1024; | |
86 | buffer = xmalloc(size); | |
c4fba0a3 CR |
87 | if (read_fd(0, &buffer, &size)) { |
88 | free(buffer); | |
975e0daf | 89 | die("could not read the input"); |
c4fba0a3 | 90 | } |
975e0daf | 91 | |
f653aee5 | 92 | size = stripspace(buffer, size, strip_comments); |
975e0daf CR |
93 | write_or_die(1, buffer, size); |
94 | if (size) | |
95 | putc('\n', stdout); | |
96 | ||
97 | free(buffer); | |
a3e870f2 LT |
98 | return 0; |
99 | } |