english
version "1.0"
identify "wxyz"

#: Copyright (c) 1995, 1996, 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 history

#: This module implements the history file for SVMS.  Basically, there is
#, a one-to-one correspondence between an h. file and a {history} object.
#,
#, A {history} object basically corresponds to a vector of {delta} objects
#, and a vector of {version} objects.  A {version} object corresponds to
#, a particular instance of a source file.  A {version} object has no
#, project, timestamp, or ancestor information.  A {delta} object names
#, a {version} object and specifies a corresponding project and timestamp.

define history				#: A history file in memory
    record
	create_timestamp unsigned	#: Creation timestamp
	deltas vector[delta]		#: Delta list
	major unsigned			#: Major version number
	minor unsigned			#: Minor version number
	project_file project_file	#: Corresponding {project_file}
	ranges_invalid logical		#: Range {chunks} are invalidated
	resources resources		#: Parent {resources} object
	versions vector[version]	#: Version list
    generate address_get, allocate, erase, identical, print



#: {history} procedures:

procedure xallocate@history
    takes
	project_file project_file
    returns history

    #: This procedure will allocate and return a new {history} object
    #, corresponding to {project_file}.

    #: Carefully reinitialize {history}:

procedure create@history
    takes
	project_file project_file
    returns history

    #: This procedure will create and return a fresh {history} object
    #, corresponding to {project_file}.


procedure deallocate@history
    takes
	history history
    returns_nothing

    #: This procedure will deallocate {history} for subsequent reallocation.


procedure delta_append@history
    takes
	history history
	delta delta
    returns_nothing

    #: This procedurew will append {delta} to the deltas in {history}.


#procedure dump@history
#    takes
#	history history
#	message string
#    returns_nothing
#
#    #: This procedure will dump out selected portions of {history} and
#    #, and label each portion with {message}.
#
#    debug_stream :@= history.resources.global.debug_stream
#    deltas :@= history.deltas
#    size :@= deltas.size
#    index :@= 0
#    loop
#	while index < size
#	delta :@= deltas[index]
#	format@format3[string, unsigned, address](debug_stream,
#	  'dump@history(%ds%): deltas[%d%]: %X%\n\',
#	  message, index, delta.address)
#	index :+= 1


procedure ranges_remove@history
    takes
	history history
    returns_nothing

    #: This procedure will remove the range chunks from all {version} objects
    #, in {history}.


procedure read@history
    takes
	data_in_stream data_in_stream
	project_file project_file
	read_timer timer
    returns history

    #: This procedure will read in the header file information for {history}
    #, from {in_stream}.  If any errors occur, an error message is output
    #, to {error_stream} and {true} is returned.


procedure save@history
    takes
	history history
	save_timer timer
    returns logical

    #: This procedure will save {history} out to disk.  If any error
    #, occurs, {true} is returned; otherwise, {false} is returned.


procedure unshare@history
    takes
	history history
	share_table set[chunk]
    returns_nothing

    #: This procedure will empty out the shared {chunks} in {share_table}.


procedure version_append@history
    takes
	history history
	version version
    returns_nothing

    #: This procedurew will append {version} to the versions in {history}.


procedure write@history
    takes
	history history
	data_out_stream data_out_stream
	write_timer timer
    returns_nothing

    #: This procedure will write {history} to {out_stream}.
    #, {global} contains some useful stuff.

    #, here is to obtain determanistic chunk sharing amongst {version}'s
    #, even after merging branches.  The first step is to sort the
    #, versions into a consistent and repeatable order.  The second
    #, step is to assign a unique number to each version.  The third
    #, step is to carefully write out each version looking for sharing
    #, as we go along (that tricky code is in {version}@{write}() .)
    #, The fourth and final step is to clean up the sharing table in
    #, {history}.

    #, and delta:
    #, in {write}@{version}():