mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-15 05:44:58 +00:00
Estimated hours taken: 30 Modified files -------------- samples/diff/Mmakefile: Minor documentation update. samples/diff/README: samples/diff/TODO: Update stuff that's now done, do a couple of minor wording changes. samples/diff/diff.m: Fix case of identical filenames (which implicitly assumed no_diff_implies_no_output). Add new match pass, call the new diff algorithm. samples/diff/diff_out.m: Add --cvs-merge-conflict output style. Slight reorganisation of top-level predicate. Lots of small fixes to use better syntax (e.g. functional style for integer maths operations). samples/diff/difftype.m: Added first_mentioned_positions/3, last_mentioned_positions/3, add_edit/4. samples/diff/file.m: Use io__read_line_as_string. samples/diff/filter.m: Minor syntax/wording changes. samples/diff/options.m: Update all the newly handled options. New files --------- samples/diff/myers.m: New diff algorithm. samples/diff/match.m: New pass to match common lines in the files to be diffed. Removed file ------------ samples/diff/lcss.m: Functionality replaced by myers.m.
126 lines
3.8 KiB
Mathematica
126 lines
3.8 KiB
Mathematica
%-----------------------------------------------------------------------------%
|
|
% Copyright (C) 1995-1998 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
|
|
% Based heavily on lcsstype.m, written by bromage and simplified by
|
|
% Marnix Klooster <marnix@worldonline.nl>
|
|
|
|
% This module contains the type of a diff.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- module difftype.
|
|
|
|
:- interface.
|
|
:- import_module std_util, list.
|
|
|
|
% A pos is a non-negative number representing a position in a
|
|
% list. The position before all elements is 0, the one
|
|
% between the first and second elements is 1, etc.
|
|
:- type pos == int.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% A segment is a pair of positions. Numbering items from 0,
|
|
% segment P-Q stands for items P up to, but not including, Q.
|
|
% (Rationale: see the interpretation of type pos above.)
|
|
%
|
|
% Invariant: In any segment X - Y, it should always be true
|
|
% that X =< Y. If X=Y, the segment is empty.
|
|
:- type segment == pair(pos,pos).
|
|
|
|
% An edit operation is an addition, a deletion or a change.
|
|
:- type edit --->
|
|
add(pos,segment)
|
|
; delete(segment,pos)
|
|
; change(segment,segment).
|
|
|
|
% The complete diff of two file is a list of edit
|
|
% operations.
|
|
%
|
|
% Invariant: The edits must be in order, and must
|
|
% not overlap or touch.
|
|
:- type diff == list(edit).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- pred first_mentioned_positions(edit :: in, pos :: out, pos :: out) is det.
|
|
|
|
:- pred last_mentioned_positions(edit :: in, pos :: out, pos :: out) is det.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% Add an edit to the start of a diff, producing a new diff.
|
|
% This predicate determines what kind of edit this is, and
|
|
% merges with the adjacent edits if appropriate.
|
|
:- pred difftype__add_edit(segment, segment, diff, diff).
|
|
:- mode difftype__add_edit(in, in, in, out) is det.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
:- import_module int.
|
|
|
|
first_mentioned_positions(add(X, Y - _), X, Y).
|
|
first_mentioned_positions(delete(X - _, Y), X, Y).
|
|
first_mentioned_positions(change(X - _, Y - _), X, Y).
|
|
|
|
last_mentioned_positions(add(X, _ - Y), X, Y).
|
|
last_mentioned_positions(delete(_ - X, Y), X, Y).
|
|
last_mentioned_positions(change(_ - X, _ - Y), X, Y).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
difftype__add_edit(X1 - X2, Y1 - Y2, [], Diff) :-
|
|
( X1 = X2 ->
|
|
( Y1 = Y2 ->
|
|
Diff = []
|
|
;
|
|
Diff = [add(X1, Y1 - Y2)]
|
|
)
|
|
;
|
|
( Y1 = Y2 ->
|
|
Diff = [delete(X1 - X2, Y1)]
|
|
;
|
|
Diff = [change(X1 - X2, Y1 - Y2)]
|
|
)
|
|
).
|
|
difftype__add_edit(X1 - X2, Y1 - Y2, [Edit0 | Diff0], Diff) :-
|
|
( Edit0 = add(X2, Y2 - Y3) ->
|
|
( X1 = X2 ->
|
|
Diff = [add(X1, Y1 - Y3) | Diff0]
|
|
;
|
|
Diff = [change(X1 - X2, Y1 - Y3) | Diff0]
|
|
)
|
|
; Edit0 = delete(X2 - X3, Y2) ->
|
|
( Y1 = Y2 ->
|
|
Diff = [delete(X1 - X3, Y1) | Diff0]
|
|
;
|
|
Diff = [change(X1 - X3, Y1 - Y2) | Diff0]
|
|
)
|
|
; Edit0 = change(X2 - X3, Y2 - Y3) ->
|
|
Diff = [change(X1 - X3, Y1 - Y3) | Diff0]
|
|
;
|
|
% This is just copied from the base case. Pretty much.
|
|
( X1 = X2 ->
|
|
( Y1 = Y2 ->
|
|
Diff = [Edit0 | Diff0]
|
|
;
|
|
Diff = [add(X1, Y1 - Y2), Edit0 | Diff0]
|
|
)
|
|
;
|
|
( Y1 = Y2 ->
|
|
Diff = [delete(X1 - X2, Y1), Edit0 | Diff0]
|
|
;
|
|
Diff = [change(X1 - X2, Y1 - Y2), Edit0 | Diff0]
|
|
)
|
|
)
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|