package versiontree class VersionMgr { # root of mainline #private Branch root_ # list of orphan branches whose parents no longer exist private tcllist orphans_ # feature branch name to Branch objref mapping private tclarray FBmap_ # version name to Snapshot objref mapping private tclarray SSmap_ # version name to GridItem objref mapping private tclarray GImap_ VersionMgr {} { } # # this method defines what constitutes a mainline version. # # for me, a mainline version is one where all the major # # and minor numbers are digits, and the number of dots # # in the version is 2. # private tclbool onMainline {tclstring.version} { # return [regexp {^[0-9]+\.[0-9]+\.[0-9]+$} $version] # } # add a version to the tree. if the snapshot number # of the version is 1, then it is a branch (could be # a branch on the mainline, though). Snapshot addVersion {tclstring.version tcllist.parents {tclbool.ghost 0}} { objref Branch br # all versions have a snapshot number, so pluck it off set ss [string range [file extension $version] 1 end] set brname [file rootname $version] set br [getBranch $brname] # create the branch if it doesn't already exist if { $br == "null" } { # create the feature branch set br [new Branch $brname $ghost] # map this entry set FBmap_($brname) $br } # create the Snapshot object set s [new Snapshot $version $ghost] # map the entry set SSmap_($version) $s # add the snapshot to the branch $br addChild $s set valid [addParents $s $parents] if { $valid == 0 } { # uh oh, no parents. He's an orphan # don't print out a warning if the mainline list is empty # because this is probably the root if { [llength $orphans_] != 0 } { VersionTree puts "Warning: version $version has no valid parents; tree may be disjoint" } # stick him on the orphan list if { [lsearch -exact $orphans_ $br] == -1 } { lappend orphans_ $br } } return $s } # this adds a parent version to a child version. If the # parent doesn't have the same root, it is considered a # merge, unless it's on the mainline. # returns the number of valid parents (ones that actually # exist) tclint addParents {Snapshot.child tcllist.parents} { set childversion [$child getName] set childbranchname [file rootname $childversion] set childnum [$child getNum] tclint valid tclbool ghost foreach parent $parents { set ghost 0 # if we use prcs info --sort date, we are guaranteed # that the parent version has already been processed # and exists in our map. objref Snapshot po [getSnapshot $parent] # but we need to handle the possibility that the parent # has since been deleted and no longer exists if { $po == "null" } { # we'll have to create a ghost version set po [addVersion $parent {} 1] set ghost 1 } # is it a merge parent or a branch? if { $childbranchname != [file rootname $parent] } { # branches occur on ss 1 if { $childnum == 1 } { # get the Branch object objref Branch br [getBranch $childbranchname] $po addBranch $br incr valid } else { # the parent is from a merge. add the parent to the # child's merge parents list $child addMergeParent $po # let the parent know he's a parent so he can update # his reference count $po addMergeChild $child # this is a valid parent only if it was not a ghost if { ! $ghost } { incr valid } } } else { # the child is a vertical branch (a snapshot increment) $child setVParent $po incr valid } } return $valid } Branch getRoot {} { return [lindex $orphans_ 0] } tcllist getOrphans {} { return $orphans_ } void mapGridItem {tclstring.version GridItem.i} { set GImap_($version) $i } void mapSnapshot {tclstring.version Snapshot.s} { set SSmap_($version) $s } GridItem getGridItem {tclstring.version} { if { [info exists GImap_($version)] } { return $GImap_($version) } { return null } } Snapshot getSnapshot {tclstring.version} { if { [info exists SSmap_($version)] } { return $SSmap_($version) } { return null } } Branch getBranch {tclsrting.version} { if { [info exists FBmap_($version)] } { return $FBmap_($version) } { return null } } }