depgraph/src/DependencyGraph.i3


--------------------------------------------------------------------------
INTERFACE DependencyGraph;

IMPORT Pathname, Wr;
IMPORT StdDepGraphNode, StdDepGraphNodeSeq;
--------------------------------------------------------------------------
VAR paranoid := FALSE;
--------------------------------------------------------------------------
TYPE
  (*
    The UpdateClosure defines two predicates that are used to determine
    the condition that a node has to be updated, which is if (a) it does
    not exist or (b) any of its predecessors in the graph is newer.
  *)
  UpdateClosure = OBJECT
  METHODS
    exists(node : StdDepGraphNode.T) : BOOLEAN;
    newer(pred, node : StdDepGraphNode.T) : BOOLEAN;
  END;

  (*
     This is the public interface of a dependency graph. Nodes are
     referenced by their names (which must be unique) and may be added
     via addElem(). Nodes have an associated action (which is
     considered to be able to `update' the node) and may be `phony'
     (in which case the node will always be considered to need an
     update).

     Dependencies are added by addDependency() and removed by
     removeDependency(); they may also be extracted from a makefile
     dependency line (like `a: b c d') by addMakefileDependencies() or
     read directly from a depend file (as constructed by gcc -M -MG,
     for example) by AddFromDependFile().

     If the graph is acyclic, topologicalSort() returns an ordered
     sequence of all the nodes (if not, a checked runtime error
     occurs).

     nodesToBeUpdated(target) returns an ordered sequence of nodes
     that need to be updated in order to update node `target'.

  *)

  Public = OBJECT
  METHODS
    init(udc : UpdateClosure) : T;
    save(fn : Pathname.T) : BOOLEAN;
    load(fn : Pathname.T) : BOOLEAN;
    saveAsText(fn : Pathname.T) : BOOLEAN;
    loadAsText(fn : Pathname.T) : BOOLEAN;
    dump(wr : Wr.T);
    reset();
    addElem(n : TEXT; action : TEXT := NIL; phony := FALSE);
    addDependency(source, dest : TEXT);
    removeDependency(source, dest : TEXT);
    addMakefileDependencies(deps : TEXT);
    addFromDependFile(fn : Pathname.T) : BOOLEAN;
    nodes() : StdDepGraphNodeSeq.T;
    nodeExists(name : TEXT) : BOOLEAN;
    getNode(name : TEXT) : StdDepGraphNode.T;
    topologicalSort() : StdDepGraphNodeSeq.T;
    nodesToBeUpdated(target : TEXT) : StdDepGraphNodeSeq.T;
    dependingNodes(start : TEXT) : StdDepGraphNodeSeq.T;
    nodeDependencies(start : TEXT) : StdDepGraphNodeSeq.T;
    setUpdateClosure(udc : UpdateClosure);
  END;

  T <: Public;
--------------------------------------------------------------------------
PROCEDURE New(udc : UpdateClosure) : T;
  (* Create a new empty dependency graph. *)
--------------------------------------------------------------------------
PROCEDURE Init(self : T; udc : UpdateClosure) : T;
  (* Initialize a dependency graph. *)
--------------------------------------------------------------------------
PROCEDURE SetUpdateClosure(self : T; udc : UpdateClosure);
  (* Define a new update closure for the graph. *)
--------------------------------------------------------------------------
PROCEDURE Save(self : T; fn : Pathname.T) : BOOLEAN;
  (* Save the actual dependency graph in a file named `fn'. Return TRUE
     on success. *)
--------------------------------------------------------------------------
PROCEDURE Load(self : T; fn : Pathname.T) : BOOLEAN;
  (* Load a new dependency graph from the file `fn'. Return TRUE on
     success. *)
--------------------------------------------------------------------------
PROCEDURE SaveAsText(self : T; fn : Pathname.T) : BOOLEAN;
  (* Save the actual dependency graph in a file named `fn' in ASCII
     representation. Return TRUE on success. *)
--------------------------------------------------------------------------
PROCEDURE LoadAsText(self : T; fn : Pathname.T) : BOOLEAN;
  (* Load a new dependency graph from the file `fn' in ASCII representation.
     Return TRUE on success. *)
--------------------------------------------------------------------------
PROCEDURE Dump(self : T; wr : Wr.T);
  (* Dump the actual dependency graph onto stream `wr'. *)
--------------------------------------------------------------------------
PROCEDURE Reset(self : T);
  (* Reset all hit markers in the dependency graph. *)
--------------------------------------------------------------------------
PROCEDURE AddElem(self : T; n: TEXT; action : TEXT := NIL; phony := FALSE);
  (* Add a new element to the dependency graph. If it is a derived file,
     a command to create or update it should be supplied in `action',
     otherwise `action' must be NIL. *)
--------------------------------------------------------------------------
PROCEDURE AddDependency(self : T; source, dest: TEXT);
  (* Add a new dependency: `dest' depends on `source'. *)
--------------------------------------------------------------------------
PROCEDURE RemoveDependency(self : T; source, dest : TEXT);
  (* Remove any dependencies from `source' to `dest'. *)
--------------------------------------------------------------------------
PROCEDURE AddMakefileDependencies(self : T; deps : TEXT);
  (* Add all dependencies from `dep', which lists them in Makefile style. *)
--------------------------------------------------------------------------
PROCEDURE AddFromDependFile(self : T; fn : Pathname.T) : BOOLEAN;
  (* Add all dependencies from makefile `fn'. Return TRUE if the file has
     been read successfully. *)
--------------------------------------------------------------------------
PROCEDURE TopologicalSort(self : T) : StdDepGraphNodeSeq.T;
  (* Return a topologically sorted sequence of nodes, if possible. *)
--------------------------------------------------------------------------
PROCEDURE Nodes(self : T) : StdDepGraphNodeSeq.T;
  (* Return the list of all nodes of the graph. *)
--------------------------------------------------------------------------
PROCEDURE NodesToBeUpdated(self : T; target : TEXT) : StdDepGraphNodeSeq.T;
  (* Return the list of nodes must be updated to update `target'. *)
--------------------------------------------------------------------------
PROCEDURE DependingNodes(self : T; start : TEXT) : StdDepGraphNodeSeq.T;
  (* Return the list of nodes that are dependend on node `start'. *)
--------------------------------------------------------------------------
PROCEDURE NodeDependencies(self : T; start : TEXT) : StdDepGraphNodeSeq.T;
  (* Return the list of nodes that node `start' depends on. *)
--------------------------------------------------------------------------
PROCEDURE NodeExists(self : T; f : TEXT) : BOOLEAN;
--------------------------------------------------------------------------
PROCEDURE GetNode(self : T; f : TEXT) : StdDepGraphNode.T;

END DependencyGraph.