Skip to content

Commit b5767dd

Browse files
author
Junio C Hamano
committed
apply --whitespace fixes and enhancements.
In addition to fixing obvious command line parsing bugs in the previous round, this changes the following: * Adds "--whitespace=strip". This applies after stripping the new trailing whitespaces introduced to the patch. * The output error message format is changed to say "patch-filename:linenumber:contents of the line". This makes it similar to typical compiler error message format, and helps C-x ` (next-error) in Emacs compilation buffer. * --whitespace=error and --whitespace=warn do not stop at the first error. We might want to limit the output to say first 20 such lines to prevent cluttering, but on the other hand if you are willing to hand-fix after inspecting them, getting everything with a single run might be easier to work with. After all, somebody has to do the clean-up work somewhere. Signed-off-by: Junio C Hamano <junkio@cox.net>
1 parent 19bfcd5 commit b5767dd

File tree

1 file changed

+54
-23
lines changed

1 file changed

+54
-23
lines changed

apply.c

Lines changed: 54 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,11 @@ static const char apply_usage[] =
3737
static enum whitespace_eol {
3838
nowarn,
3939
warn_on_whitespace,
40-
error_on_whitespace
40+
error_on_whitespace,
41+
strip_and_apply,
4142
} new_whitespace = nowarn;
43+
static int whitespace_error = 0;
44+
static const char *patch_input_file = NULL;
4245

4346
/*
4447
* For "diff-stat" like behaviour, we keep track of the biggest change
@@ -823,19 +826,17 @@ static int parse_fragment(char *line, unsigned long size, struct patch *patch, s
823826
case '+':
824827
/*
825828
* We know len is at least two, since we have a '+' and
826-
* we checked that the last character was a '\n' above
829+
* we checked that the last character was a '\n' above.
830+
* That is, an addition of an empty line would check
831+
* the '+' here. Sneaky...
827832
*/
828-
if (isspace(line[len-2])) {
829-
switch (new_whitespace) {
830-
case nowarn:
831-
break;
832-
case warn_on_whitespace:
833-
new_whitespace = nowarn; /* Just once */
834-
error("Added whitespace at end of line at line %d", linenr);
835-
break;
836-
case error_on_whitespace:
837-
die("Added whitespace at end of line at line %d", linenr);
838-
}
833+
if ((new_whitespace != nowarn) &&
834+
isspace(line[len-2])) {
835+
fprintf(stderr, "Added whitespace\n");
836+
fprintf(stderr, "%s:%d:%.*s\n",
837+
patch_input_file,
838+
linenr, len-2, line+1);
839+
whitespace_error = 1;
839840
}
840841
added++;
841842
newlines--;
@@ -1114,6 +1115,27 @@ struct buffer_desc {
11141115
unsigned long alloc;
11151116
};
11161117

1118+
static int apply_line(char *output, const char *patch, int plen)
1119+
{
1120+
/* plen is number of bytes to be copied from patch,
1121+
* starting at patch+1 (patch[0] is '+'). Typically
1122+
* patch[plen] is '\n'.
1123+
*/
1124+
int add_nl_to_tail = 0;
1125+
if ((new_whitespace == strip_and_apply) &&
1126+
1 < plen && isspace(patch[plen-1])) {
1127+
if (patch[plen] == '\n')
1128+
add_nl_to_tail = 1;
1129+
plen--;
1130+
while (0 < plen && isspace(patch[plen]))
1131+
plen--;
1132+
}
1133+
memcpy(output, patch + 1, plen);
1134+
if (add_nl_to_tail)
1135+
output[plen++] = '\n';
1136+
return plen;
1137+
}
1138+
11171139
static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag)
11181140
{
11191141
char *buf = desc->buffer;
@@ -1149,10 +1171,9 @@ static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag)
11491171
break;
11501172
/* Fall-through for ' ' */
11511173
case '+':
1152-
if (*patch != '+' || !no_add) {
1153-
memcpy(new + newsize, patch + 1, plen);
1154-
newsize += plen;
1155-
}
1174+
if (*patch != '+' || !no_add)
1175+
newsize += apply_line(new + newsize, patch,
1176+
plen);
11561177
break;
11571178
case '@': case '\\':
11581179
/* Ignore it, we already handled it */
@@ -1721,14 +1742,15 @@ static int use_patch(struct patch *p)
17211742
return 1;
17221743
}
17231744

1724-
static int apply_patch(int fd)
1745+
static int apply_patch(int fd, const char *filename)
17251746
{
17261747
int newfd;
17271748
unsigned long offset, size;
17281749
char *buffer = read_patch_file(fd, &size);
17291750
struct patch *list = NULL, **listp = &list;
17301751
int skipped_patch = 0;
17311752

1753+
patch_input_file = filename;
17321754
if (!buffer)
17331755
return -1;
17341756
offset = 0;
@@ -1755,6 +1777,9 @@ static int apply_patch(int fd)
17551777
}
17561778

17571779
newfd = -1;
1780+
if (whitespace_error && (new_whitespace == error_on_whitespace))
1781+
apply = 0;
1782+
17581783
write_index = check_index && apply;
17591784
if (write_index)
17601785
newfd = hold_index_file_for_update(&cache_file, get_index_file());
@@ -1801,7 +1826,7 @@ int main(int argc, char **argv)
18011826
int fd;
18021827

18031828
if (!strcmp(arg, "-")) {
1804-
apply_patch(0);
1829+
apply_patch(0, "<stdin>");
18051830
read_stdin = 0;
18061831
continue;
18071832
}
@@ -1862,14 +1887,18 @@ int main(int argc, char **argv)
18621887
continue;
18631888
}
18641889
if (!strncmp(arg, "--whitespace=", 13)) {
1865-
if (strcmp(arg+13, "warn")) {
1890+
if (!strcmp(arg+13, "warn")) {
18661891
new_whitespace = warn_on_whitespace;
18671892
continue;
18681893
}
1869-
if (strcmp(arg+13, "error")) {
1894+
if (!strcmp(arg+13, "error")) {
18701895
new_whitespace = error_on_whitespace;
18711896
continue;
18721897
}
1898+
if (!strcmp(arg+13, "strip")) {
1899+
new_whitespace = strip_and_apply;
1900+
continue;
1901+
}
18731902
die("unrecognixed whitespace option '%s'", arg+13);
18741903
}
18751904

@@ -1885,10 +1914,12 @@ int main(int argc, char **argv)
18851914
if (fd < 0)
18861915
usage(apply_usage);
18871916
read_stdin = 0;
1888-
apply_patch(fd);
1917+
apply_patch(fd, arg);
18891918
close(fd);
18901919
}
18911920
if (read_stdin)
1892-
apply_patch(0);
1921+
apply_patch(0, "<stdin>");
1922+
if (whitespace_error && new_whitespace == error_on_whitespace)
1923+
return 1;
18931924
return 0;
18941925
}

0 commit comments

Comments
 (0)