english
version "1.0"
identify "@(#)differ.sts 1.2 96/02/25"
#: Copyright (c) 1995, 2002 by Wayne C. Gramlich.
#, All rights reserved.
#,
#, Permission to use, copy, modify, distribute, and sell this software
#, for any purpose is hereby granted without fee provided that the above
#, copyright notice and this permission are retained. The author makes
#, no representations about the suitability of this software for any purpose.
#, It is provided "as is" without express or implied warranty.
module differ
#: This module implements algorithms for determining the differences
#, between sequences of objects. This code is parameterized so that
#, it can work on any arbitrary sequence of objects (e.g. vector[item],
#, string, etc.)
define align_type #: Alignment type
enumeration
differ #: Alignment is different
same #: Alignemnt is the same
smashed #: Alignment is smashed
generate equal, print
define align[item] #: One set of alignments
record
differ_table differ_table[item] #: Parent {differ_table}
sequence1 sequence[item] #: First sequence
sequence2 sequence[item] #: Second sequence
type align_type #: Alignment type
generate address_get, allocate, erase, identical
define aligns[item] #: Sequence of {align} objects
record
differ_table differ_table[item] #: Parent {differ_table}
list vector[align[item]] #: List of {align} objects
generate address_get, allocate, erase, identical
define differ_table[item] #: Some tables for computing diffs
record
debug_stream out_stream #: Debugging stream
aligns aligns[item] #: Temp. align list
aligns_free aligns[item] #: Free diff. list
matches vector[match[item]] #: Temp. match list
matches_free vector[match[item]] #: Free match list
match_table table[item, match[item]] #: Match table for unique lines
table set[sequence[item]] #: Table for lookups
sequences vector[sequence[item]] #: Temp. sequences list
sequences_free vector[sequence[item]] #: Free sequences list
generate allocate, erase, identical, print
define match[item] #: On set of matches
record
differ_table differ_table[item] #: Parent {differ_table}
item item #: Matching item
index1 unsigned #: First matching index
index2 unsigned #: Second matching index
generate address_get, allocate, erase, identical
define sequence[item] #: A sequence of {item} objects
record
differ_table differ_table[item] #: Parent {differ_table}
items vector[item] #: Object sequence is part of
items_hash unsigned #: Hash value for {items}
start unsigned #: Start offset of sequence
length unsigned #: Number of objects in sequence
generate address_get, allocate, erase, identical
#: {align} procedures:
procedure deallocate@align[item]
takes
align align[item]
returns_nothing
#: This procedure will deallocate {sequence}.
procedure greater_than@align[item]
takes
align1 align[item]
align2 align[item]
returns logical
#: This procedure return {true} if {align1} is greater than {align2}
#, with no overlap or {false} otherwise.
procedure is_smashed@align[item]
takes
align align[item]
returns logical
#: This procedure returns {true} if {align} is "smashed" and {false}
#, otherwise.
procedure less_than@align[item]
takes
align1 align[item]
align2 align[item]
returns logical
#: This procedure return {true} if {align1} is less than {align2}
#, with no overlap or {false} otherwise.
procedure print@align[item]
takes
align align[item]
out_stream out_stream
returns_nothing
procedure smash@align[item]
takes
align align[item]
returns_nothing
#: This procedure will mark {align} as an empty sequence.
#: {aligns} procedures:
procedure append@aligns[item]
takes
aligns aligns[item]
align align[item]
returns_nothing
#: This procedure will append {align} to {aligns}.
procedure create@aligns[item]
takes
differ_table differ_table[item]
returns aligns[item]
#: This procedure will create and return a new {aligns} object
#, containing {differ_table}.
procedure cull@aligns[item]
takes
aligns aligns[item]
returns_nothing
#: This procedure will remove any {align} objects from {aligns}
#, that are "smashed".
procedure differ_insert@aligns[item]
takes
aligns aligns[item]
items1 vector[item]
items2 vector[item]
returns_nothing
#: This procedure will add all of the differing {align} objects
#, {aligns}.
procedure fetch1@aligns[item]
takes
aligns aligns[item]
index unsigned
returns align[item]
#: This procedure will return the {index}'th {align} object from {aligns}.
procedure order@aligns[item]
takes
aligns aligns[item]
start unsigned
length unsigned
returns_nothing
#: This procedure will order {aligns} so that all {align} objects
#, between {start} and {start} + {length} - 1 are ordered before
#, or after the largest matching region.
procedure pop@aligns[item]
takes
aligns aligns[item]
returns align[item]
#: This procedure will return the {align} object at the end of {aligns}
#, and reduce the size of {aligns} by one.
procedure print@aligns[item]
takes
aligns aligns[item]
out_stream out_stream
returns_nothing
#: This procedure will print {aligns} to {out_stream}.
procedure size_get@aligns[item]
takes
aligns aligns[item]
returns unsigned
#: This procedure will return the size of {aligns}.
procedure store1@aligns[item]
takes
aligns aligns[item]
index unsigned
align align[item]
returns_nothing
#: This procedure will store {align} into {aligns}.
procedure truncate@aligns[item]
takes
aligns aligns[item]
new_size unsigned
returns_nothing
#: This procedure will trucate {aligns} to only have {new_size}
#, {align} objects.
procedure verify@aligns[item]
takes
aligns aligns[item]
label string
returns_nothing
#: This procedure will verify that {aligns} is well ordered.
#: {differ_table} procedures:
procedure align_allocate@differ_table[item]
takes
differ_table differ_table[item]
type align_type
items1 vector[item]
start1 unsigned
length1 unsigned
items2 vector[item]
start2 unsigned
length2 unsigned
returns align[item]
#: This procedure will allocate and return a new {align} object
#, containing {items1}, {start1}, {length2}, {items2},
#, {start2}, and {length2}.
procedure align_deallocate@differ_table[item]
takes
differ_table differ_table[item]
align align[item]
returns_nothing
#: This procedure will deallocate {align} for {differ_table}.
procedure aligns_find@differ_table[item]
takes
differ_table differ_table[item]
items1 vector[item]
items2 vector[item]
returns aligns[item]
needs
procedure equal@item
takes item, item
returns logical
procedure hash@item
takes item
returns unsigned
procedure identical@item
takes item, item
returns logical
#: This procedure will return all of the alignments between
#, {items1} and {items2} using {differ_table} to hold all of
#, the intermediate state:
procedure aligns_match@differ_table[item]
takes
differ_table differ_table[item]
items1 vector[item]
items2 vector[item]
returns aligns[item]
needs
procedure equal@item
takes item, item
returns logical
procedure hash@item
takes item
returns unsigned
procedure identical@item
takes item, item
returns logical
#: This procedure will identify and return the initial matching
#, {align} objects for each matching span in {items1} and {itmes2}
#, that contains a single uniquely matching {item}.
#, is to find items that occur exactly once in {items1} and
#, {items2}. These items are high probability match ups.
#, The second step is to use a heavier weight alogrithm to
#, find matches in the remaining unmatched sections.
procedure create@differ_table[item]
takes_nothing
returns differ_table[item]
#: This procedure will create and return a new {differ_table} object.
procedure match_allocate@differ_table[item]
takes
differ_table differ_table[item]
returns match[item]
#: This procedure will allocate and return a {match} object from
#, {differ_table}.
procedure match_deallocate@differ_table[item]
takes
differ_table differ_table[item]
match match[item]
returns_nothing
#: This procedure will deallocate {match} into {differ_table}.
procedure match_expand@differ_table[item]
takes
differ_table differ_table[item]
match match[item]
items1 vector[item]
items2 vector[item]
returns align[item]
needs
procedure equal@item
takes item, item
returns logical
procedure hash@item
takes item
returns unsigned
#: This procedure will expand {match} until is spans as many
#, matching items as possible.
#: Look for previous matching items:
procedure sequence_allocate@differ_table[item]
takes
differ_table differ_table[item]
items vector[item]
start unsigned
length unsigned
returns sequence[item]
#: This procedure will allocate and return an uninitialized
#, {sequence} object from {differ_table}.
procedure sequence_deallocate@differ_table[item]
takes
differ_table differ_table[item]
sequence sequence[item]
returns_nothing
#: This procedure will deallocate {sequence} into {differ_table}.
#: {match} procedures:
procedure deallocate@match[item]
takes
match match[item]
returns_nothing
#: This procedure will deallocate {match}.
procedure print@match[item]
takes
match match[item]
out_stream out_stream
returns_nothing
procedure smash@match[item]
takes
match match[item]
returns_nothing
#: This procedure will set the contents of {match} so that it
#, no longer indicates a match.
#: {sequence} procedures:
procedure deallocate@sequence[item]
takes
sequence sequence[item]
returns_nothing
#: This procedure will deallocate {sequence}.
procedure equal@sequence[item]
takes
sequence1 sequence[item]
sequence2 sequence[item]
returns logical
needs
procedure equal@item
takes item, item
returns logical
#: This procedure will return {true} if {sequence1} equals {sequence2}
#, and {false} otherwise.
procedure greater_than@sequence[item]
takes
sequence1 sequence[item]
sequence2 sequence[item]
returns logical
#: This procedure will return {true} if {sequence1} is greater than
#, {sequence2} with no overlap; otherwise, {false} is returned.
procedure hash@sequence[item]
takes
sequence sequence[item]
returns unsigned
needs
procedure hash@item
takes item
returns unsigned
#: This procedure will return a hash value for {sequence}.
procedure less_than@sequence[item]
takes
sequence1 sequence[item]
sequence2 sequence[item]
returns logical
#: This procedure will return {true} if {sequence1} is less than
#, {sequence2} with no overlap; otherwise, {false} is returned.
procedure print@sequence[item]
takes
sequence sequence[item]
out_stream out_stream
returns_nothing
needs
procedure print@item
takes item, out_stream
returns_nothing
#: This procedure outputs {sequence} to {out_stream}.
procedure show_prefixed@sequence[item]
takes
sequence sequence[item]
prefix string
out_stream out_stream
returns_nothing
needs
procedure show_prefixed@item
takes item, string, out_stream
returns_nothing
#: This procedure will output {sequence} to {out_stream} with each
#, {item} prefixed with {prefix}.
procedure smash@sequence[item]
takes
sequence sequence[item]
returns_nothing
#: This procedure will convert {sequence} into a zero length sequence.