Skip to content

Commit 9690c11

Browse files
jasamplergitster
authored andcommitted
Fix git-stripspace to process correctly long lines and spaces.
Now the implementation gets more memory to store completely each line before removing trailing spaces, and does it right when the last line of the file ends with spaces and no newline at the end. Function stripspace needs again to be non-static in order to call it from "builtin-tag.c" and the upcoming "builtin-commit.c". A new parameter skip_comments was also added to the stripspace function to optionally strips every shell #comment from the input, needed for doing this task on those programs. Signed-off-by: Carlos Rica <jasampler@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 384f122 commit 9690c11

File tree

2 files changed

+46
-24
lines changed

2 files changed

+46
-24
lines changed

builtin-stripspace.c

Lines changed: 45 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,79 @@
11
#include "builtin.h"
2+
#include "cache.h"
23

34
/*
4-
* Remove empty lines from the beginning and end.
5+
* Remove trailing spaces from a line.
56
*
6-
* Turn multiple consecutive empty lines into just one
7-
* empty line. Return true if it is an incomplete line.
7+
* If the line ends with newline, it will be removed too.
8+
* Returns the new length of the string.
89
*/
9-
static int cleanup(char *line)
10+
static int cleanup(char *line, int len)
1011
{
11-
int len = strlen(line);
12+
if (len) {
13+
if (line[len - 1] == '\n')
14+
len--;
1215

13-
if (len && line[len-1] == '\n') {
14-
if (len == 1)
15-
return 0;
16-
do {
17-
unsigned char c = line[len-2];
16+
while (len) {
17+
unsigned char c = line[len - 1];
1818
if (!isspace(c))
1919
break;
20-
line[len-2] = '\n';
2120
len--;
22-
line[len] = 0;
23-
} while (len > 1);
24-
return 0;
21+
}
22+
line[len] = 0;
2523
}
26-
return 1;
24+
return len;
2725
}
2826

29-
static void stripspace(FILE *in, FILE *out)
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)
3040
{
3141
int empties = -1;
32-
int incomplete = 0;
33-
char line[1024];
42+
int alloc = 1024;
43+
char *line = xmalloc(alloc);
44+
45+
while (fgets(line, alloc, in)) {
46+
int len = strlen(line);
3447

35-
while (fgets(line, sizeof(line), in)) {
36-
incomplete = cleanup(line);
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);
3758

3859
/* Not just an empty line? */
39-
if (line[0] != '\n') {
60+
if (len) {
4061
if (empties > 0)
4162
fputc('\n', out);
4263
empties = 0;
4364
fputs(line, out);
65+
fputc('\n', out);
4466
continue;
4567
}
4668
if (empties < 0)
4769
continue;
4870
empties++;
4971
}
50-
if (incomplete)
51-
fputc('\n', out);
72+
free(line);
5273
}
5374

5475
int cmd_stripspace(int argc, const char **argv, const char *prefix)
5576
{
56-
stripspace(stdin, stdout);
77+
stripspace(stdin, stdout, 0);
5778
return 0;
5879
}

builtin.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ extern const char git_version_string[];
77
extern const char git_usage_string[];
88

99
extern void help_unknown_cmd(const char *cmd);
10+
extern void stripspace(FILE *in, FILE *out, int skip_comments);
1011
extern int write_tree(unsigned char *sha1, int missing_ok, const char *prefix);
1112
extern void prune_packed_objects(int);
1213

0 commit comments

Comments
 (0)