Skip to content

Commit 9981c80

Browse files
committed
Merge branch 'jc/maint-blank-at-eof'
* jc/maint-blank-at-eof: diff -B: colour whitespace errors diff.c: emit_add_line() takes only the rest of the line diff.c: split emit_line() from the first char and the rest of the line diff.c: shuffling code around diff --whitespace: fix blank lines at end core.whitespace: split trailing-space into blank-at-{eol,eof} diff --color: color blank-at-eof diff --whitespace=warn/error: fix blank-at-eof check diff --whitespace=warn/error: obey blank-at-eof diff.c: the builtin_diff() deals with only two-file comparison apply --whitespace: warn blank but not necessarily empty lines at EOF apply --whitespace=warn/error: diagnose blank at EOF apply.c: split check_whitespace() into two apply --whitespace=fix: detect new blank lines at eof correctly apply --whitespace=fix: fix handling of blank lines at the eof
2 parents 7641eb4 + d91ba8f commit 9981c80

File tree

8 files changed

+437
-173
lines changed

8 files changed

+437
-173
lines changed

Documentation/config.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,13 +416,17 @@ core.whitespace::
416416
consider them as errors. You can prefix `-` to disable
417417
any of them (e.g. `-trailing-space`):
418418
+
419-
* `trailing-space` treats trailing whitespaces at the end of the line
419+
* `blank-at-eol` treats trailing whitespaces at the end of the line
420420
as an error (enabled by default).
421421
* `space-before-tab` treats a space character that appears immediately
422422
before a tab character in the initial indent part of the line as an
423423
error (enabled by default).
424424
* `indent-with-non-tab` treats a line that is indented with 8 or more
425425
space characters as an error (not enabled by default).
426+
* `blank-at-eof` treats blank lines added at the end of file as an error
427+
(enabled by default).
428+
* `trailing-space` is a short-hand to cover both `blank-at-eol` and
429+
`blank-at-eof`.
426430
* `cr-at-eol` treats a carriage-return at the end of line as
427431
part of the line terminator, i.e. with it, `trailing-space`
428432
does not trigger if the character before such a carriage-return

builtin-apply.c

Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ struct fragment {
153153
const char *patch;
154154
int size;
155155
int rejected;
156+
int linenr;
156157
struct fragment *next;
157158
};
158159

@@ -1227,23 +1228,29 @@ static int find_header(char *line, unsigned long size, int *hdrsize, struct patc
12271228
return -1;
12281229
}
12291230

1230-
static void check_whitespace(const char *line, int len, unsigned ws_rule)
1231+
static void record_ws_error(unsigned result, const char *line, int len, int linenr)
12311232
{
12321233
char *err;
1233-
unsigned result = ws_check(line + 1, len - 1, ws_rule);
1234+
12341235
if (!result)
12351236
return;
12361237

12371238
whitespace_error++;
12381239
if (squelch_whitespace_errors &&
12391240
squelch_whitespace_errors < whitespace_error)
1240-
;
1241-
else {
1242-
err = whitespace_error_string(result);
1243-
fprintf(stderr, "%s:%d: %s.\n%.*s\n",
1244-
patch_input_file, linenr, err, len - 2, line + 1);
1245-
free(err);
1246-
}
1241+
return;
1242+
1243+
err = whitespace_error_string(result);
1244+
fprintf(stderr, "%s:%d: %s.\n%.*s\n",
1245+
patch_input_file, linenr, err, len, line);
1246+
free(err);
1247+
}
1248+
1249+
static void check_whitespace(const char *line, int len, unsigned ws_rule)
1250+
{
1251+
unsigned result = ws_check(line + 1, len - 1, ws_rule);
1252+
1253+
record_ws_error(result, line + 1, len - 2, linenr);
12471254
}
12481255

12491256
/*
@@ -1359,6 +1366,7 @@ static int parse_single_patch(char *line, unsigned long size, struct patch *patc
13591366
int len;
13601367

13611368
fragment = xcalloc(1, sizeof(*fragment));
1369+
fragment->linenr = linenr;
13621370
len = parse_fragment(line, size, patch, fragment);
13631371
if (len <= 0)
13641372
die("corrupt patch at line %d", linenr);
@@ -2142,6 +2150,7 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
21422150
int len = linelen(patch, size);
21432151
int plen, added;
21442152
int added_blank_line = 0;
2153+
int is_blank_context = 0;
21452154

21462155
if (!len)
21472156
break;
@@ -2174,8 +2183,12 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
21742183
*new++ = '\n';
21752184
add_line_info(&preimage, "\n", 1, LINE_COMMON);
21762185
add_line_info(&postimage, "\n", 1, LINE_COMMON);
2186+
is_blank_context = 1;
21772187
break;
21782188
case ' ':
2189+
if (plen && (ws_rule & WS_BLANK_AT_EOF) &&
2190+
ws_blank_line(patch + 1, plen, ws_rule))
2191+
is_blank_context = 1;
21792192
case '-':
21802193
memcpy(old, patch + 1, plen);
21812194
add_line_info(&preimage, old, plen,
@@ -2202,7 +2215,8 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
22022215
(first == '+' ? 0 : LINE_COMMON));
22032216
new += added;
22042217
if (first == '+' &&
2205-
added == 1 && new[-1] == '\n')
2218+
(ws_rule & WS_BLANK_AT_EOF) &&
2219+
ws_blank_line(patch + 1, plen, ws_rule))
22062220
added_blank_line = 1;
22072221
break;
22082222
case '@': case '\\':
@@ -2215,6 +2229,8 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
22152229
}
22162230
if (added_blank_line)
22172231
new_blank_lines_at_end++;
2232+
else if (is_blank_context)
2233+
;
22182234
else
22192235
new_blank_lines_at_end = 0;
22202236
patch += len;
@@ -2296,17 +2312,24 @@ static int apply_one_fragment(struct image *img, struct fragment *frag,
22962312
}
22972313

22982314
if (applied_pos >= 0) {
2299-
if (ws_error_action == correct_ws_error &&
2300-
new_blank_lines_at_end &&
2301-
postimage.nr + applied_pos == img->nr) {
2315+
if (new_blank_lines_at_end &&
2316+
preimage.nr + applied_pos == img->nr &&
2317+
(ws_rule & WS_BLANK_AT_EOF) &&
2318+
ws_error_action != nowarn_ws_error) {
2319+
record_ws_error(WS_BLANK_AT_EOF, "+", 1, frag->linenr);
2320+
if (ws_error_action == correct_ws_error) {
2321+
while (new_blank_lines_at_end--)
2322+
remove_last_line(&postimage);
2323+
}
23022324
/*
2303-
* If the patch application adds blank lines
2304-
* at the end, and if the patch applies at the
2305-
* end of the image, remove those added blank
2306-
* lines.
2325+
* We would want to prevent write_out_results()
2326+
* from taking place in apply_patch() that follows
2327+
* the callchain led us here, which is:
2328+
* apply_patch->check_patch_list->check_patch->
2329+
* apply_data->apply_fragments->apply_one_fragment
23072330
*/
2308-
while (new_blank_lines_at_end--)
2309-
remove_last_line(&postimage);
2331+
if (ws_error_action == die_on_ws_error)
2332+
apply = 0;
23102333
}
23112334

23122335
/*

cache.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -986,10 +986,12 @@ void shift_tree(const unsigned char *, const unsigned char *, unsigned char *, i
986986
* whitespace rules.
987987
* used by both diff and apply
988988
*/
989-
#define WS_TRAILING_SPACE 01
989+
#define WS_BLANK_AT_EOL 01
990990
#define WS_SPACE_BEFORE_TAB 02
991991
#define WS_INDENT_WITH_NON_TAB 04
992992
#define WS_CR_AT_EOL 010
993+
#define WS_BLANK_AT_EOF 020
994+
#define WS_TRAILING_SPACE (WS_BLANK_AT_EOL|WS_BLANK_AT_EOF)
993995
#define WS_DEFAULT_RULE (WS_TRAILING_SPACE|WS_SPACE_BEFORE_TAB)
994996
extern unsigned whitespace_rule_cfg;
995997
extern unsigned whitespace_rule(const char *);

0 commit comments

Comments
 (0)