forked from Mercury-Language/mercury
-
Notifications
You must be signed in to change notification settings - Fork 0
/
filter.m
119 lines (102 loc) · 3.75 KB
/
filter.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
%-----------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et wm=0 tw=0
%-----------------------------------------------------------------------------%
% Copyright (C) 1998, 2006 The University of Melbourne.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%-----------------------------------------------------------------------------%
%
% Main author: bromage
%
% This module contains code to filter the diff before output, based on
% the command-line options presented.
%
% At the moment, only one option is handled: --ignore-blank-lines.
% This causes edits to be dropped if they contain changes which only
% add, delete or change blank lines.
%
% TO DO: What exactly is a blank line, and does its definition change
% if --ignore-space-change or --ignore-all-space have been specified?
% At the moment, we define a blank line to be a line containing zero or more
% whitespace characters. Check if this is correct or not.
%
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
:- module filter.
:- interface.
:- import_module difftype.
:- import_module file.
:- import_module io.
%-----------------------------------------------------------------------------%
:- pred filter_diff(file::in, file::in, diff::in, diff::out,
io::di, io::uo) is det.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
:- implementation.
:- import_module globals.
:- import_module options.
:- import_module bool.
:- import_module char.
:- import_module int.
:- import_module list.
:- import_module pair.
:- import_module string.
%-----------------------------------------------------------------------------%
filter_diff(File1, File2, !Diff, !IO) :-
globals.io_lookup_bool_option(ignore_blank_lines, FilterBlank, !IO),
(
% If we didn't request a filter, skip this pass.
FilterBlank = no
;
FilterBlank = yes,
filter.blank_lines(!.Diff, File1, File2, !:Diff)
).
:- pred filter.blank_lines(diff::in, file::in, file::in, diff::out) is det.
filter.blank_lines([], _, _, []).
filter.blank_lines([Edit | Diff0], File1, File2, Diff) :-
filter.blank_lines(Diff0, File1, File2, Diff1),
(
Edit = add(_, Y1 - Y2),
( if range_has_only_blank_lines(Y1, Y2, File2) then
Diff = Diff1
else
Diff = [Edit | Diff1]
)
;
Edit = delete(X1 - X2, _),
( if range_has_only_blank_lines(X1, X2, File1) then
Diff = Diff1
else
Diff = [Edit | Diff1]
)
;
Edit = change(X1 - X2, Y1 - Y2),
( if
range_has_only_blank_lines(X1, X2, File1),
range_has_only_blank_lines(Y1, Y2, File2)
then
Diff = Diff1
else
Diff = [Edit | Diff1]
)
).
%-----------------------------------------------------------------------------%
:- pred range_has_only_blank_lines(int::in, int::in, file::in) is semidet.
range_has_only_blank_lines(First, Last, File) :-
(
First < Last
=>
(
file.get_line(File, First, Line),
string.to_char_list(Line, Chars),
all [C] (
list.member(C, Chars)
=>
char.is_whitespace(C)
),
range_has_only_blank_lines(First + 1, Last, File)
)
).
%-----------------------------------------------------------------------------%
:- end_module filter.
%-----------------------------------------------------------------------------%