summaryrefslogtreecommitdiff
path: root/tools/cvs2fossil/lib/c2f_fsym.tcl
diff options
context:
space:
mode:
Diffstat (limited to 'tools/cvs2fossil/lib/c2f_fsym.tcl')
-rw-r--r--tools/cvs2fossil/lib/c2f_fsym.tcl325
1 files changed, 325 insertions, 0 deletions
diff --git a/tools/cvs2fossil/lib/c2f_fsym.tcl b/tools/cvs2fossil/lib/c2f_fsym.tcl
new file mode 100644
index 0000000..d61b46e
--- /dev/null
+++ b/tools/cvs2fossil/lib/c2f_fsym.tcl
@@ -0,0 +1,325 @@
+## -*- tcl -*-
+# # ## ### ##### ######## ############# #####################
+## Copyright (c) 2007-2008 Andreas Kupries.
+#
+# This software is licensed as described in the file LICENSE, which
+# you should have received as part of this distribution.
+#
+# This software consists of voluntary contributions made by many
+# individuals. For exact contribution history, see the revision
+# history and logs, available at http://fossil-scm.hwaci.com/fossil
+# # ## ### ##### ######## ############# #####################
+
+## Symbols (Tags, Branches) per file.
+
+# # ## ### ##### ######## ############# #####################
+## Requirements
+
+package require Tcl 8.4 ; # Required runtime.
+package require snit ; # OO system.
+package require vc::tools::trouble ; # Error reporting.
+package require vc::fossil::import::cvs::file::rev ; # CVS per file revisions.
+package require vc::fossil::import::cvs::state ; # State storage.
+package require vc::fossil::import::cvs::integrity ; # State integrity checks.
+
+# # ## ### ##### ######## ############# #####################
+##
+
+snit::type ::vc::fossil::import::cvs::file::sym {
+ # # ## ### ##### ######## #############
+ ## Public API
+
+ constructor {symtype nr symbol file} {
+ set myfile $file
+ set mytype $symtype
+ set mynr $nr
+ set mysymbol $symbol
+
+ switch -exact -- $mytype {
+ branch { SetupBranch ; return }
+ tag { return }
+ }
+ integrity assert 0 {Bad symbol type '$mytype'}
+ return
+ }
+
+ method defid {} {
+ set myid [incr myidcounter]
+ return
+ }
+
+ method fid {} { return $myid }
+ method symbol {} { return $mysymbol }
+
+ # Symbol acessor methods.
+
+ delegate method name to mysymbol
+ delegate method id to mysymbol
+
+ # Symbol aggregation methods
+
+ delegate method countasbranch to mysymbol
+ delegate method countastag to mysymbol
+ delegate method countacommit to mysymbol
+
+ method blockedby {fsymbol} {
+ $mysymbol blockedby [$fsymbol symbol]
+ return
+ }
+
+ method possibleparents {} {
+ switch -exact -- $mytype {
+ branch { $self BranchParents }
+ tag { $self TagParents }
+ }
+ return
+ }
+
+ method BranchParents {} {
+ # The "obvious" parent of a branch is the branch holding the
+ # revision spawning the branch. Any other branches that are
+ # rooted at the same revision and were committed earlier than
+ # the branch are also possible parents.
+
+ # Ignore this if the branch symbol is detached.
+ if {$mybranchparent eq ""} return
+
+ $mysymbol possibleparent [[$mybranchparent lod] symbol]
+
+ foreach branch [$mybranchparent branches] {
+ # A branch cannot be its own parent. Nor can a branch
+ # created after this one be its parent. This means that we
+ # can abort the loop when we have reached ourselves in the
+ # list of branches. Here the order of file::rev.mybranches
+ # comes into play, as created by file::rev::sortbranches.
+
+ if {$branch eq $self} break
+ $mysymbol possibleparent [$branch symbol]
+ }
+ return
+ }
+
+ method TagParents {} {
+ # The "obvious" parent of a tag is the branch holding the
+ # revision spawning the tag. Branches that are spawned by the
+ # same revision are also possible parents.
+
+ $mysymbol possibleparent [[$mytagrev lod] symbol]
+
+ foreach branch [$mytagrev branches] {
+ $mysymbol possibleparent [$branch symbol]
+ }
+ return
+ }
+
+ #
+
+ method istrunk {} { return 0 }
+
+ # Branch acessor methods.
+
+ method setchildrevnr {revnr} {
+ integrity assert {$mybranchchildrevnr eq ""} {Child already defined}
+ set mybranchchildrevnr $revnr
+ return
+ }
+
+ method setposition {n} { set mybranchposition $n ; return }
+ method setparent {rev} { set mybranchparent $rev ; return }
+ method setchild {rev} { set mybranchchild $rev ; return }
+ method cutchild {} { set mybranchchild "" ; return }
+ method cutbranchparent {} { set mybranchparent "" ; return }
+
+ method branchnr {} { return $mynr }
+ method parentrevnr {} { return $mybranchparentrevnr }
+ method childrevnr {} { return $mybranchchildrevnr }
+ method haschildrev {} { return [expr {$mybranchchildrevnr ne ""}] }
+ method haschild {} { return [expr {$mybranchchild ne ""}] }
+ method parent {} { return $mybranchparent }
+ method child {} { return $mybranchchild }
+ method position {} { return $mybranchposition }
+
+ # Tag acessor methods.
+
+ method tagrevnr {} { return $mynr }
+ method settagrev {rev} { set mytagrev $rev ; return }
+
+ # Derived information
+
+ method lod {} { return $mylod }
+
+ method setlod {lod} {
+ set mylod $lod
+ $self checklod
+ return
+ }
+
+ method checklod {} {
+ # Consistency check. The symbol's line-of-development has to
+ # be same as the line-of-development of its source (parent
+ # revision of a branch, revision of a tag itself).
+
+ switch -exact -- $mytype {
+ branch {
+ # However, ignore this if the branch symbol is
+ # detached.
+ if {$mybranchparent eq ""} return
+
+ set slod [$mybranchparent lod]
+ }
+ tag { set slod [$mytagrev lod] }
+ }
+
+ if {$mylod ne $slod} {
+ trouble fatal "For $mytype [$mysymbol name]: LOD conflict with source, '[$mylod name]' vs. '[$slod name]'"
+ return
+ }
+ return
+ }
+
+ # # ## ### ##### ######## #############
+
+ method persist {} {
+ # Save the information we need after the collection pass.
+
+ set fid [$myfile id]
+ set sid [$mysymbol id]
+ set lod [$mylod id]
+
+ switch -exact -- $mytype {
+ tag {
+ set rid [$mytagrev id]
+ state transaction {
+ state run {
+ INSERT INTO tag ( tid, fid, lod, sid, rev)
+ VALUES ($myid, $fid, $lod, $sid, $rid);
+ }
+ }
+ }
+ branch {
+ lappend map @F@ [expr { ($mybranchchild eq "") ? "NULL" : [$mybranchchild id] }]
+ lappend map @P@ [expr { ($mybranchparent eq "") ? "NULL" : [$mybranchparent id] }]
+
+ set cmd {
+ INSERT INTO branch ( bid, fid, lod, sid, root, first, bra, pos )
+ VALUES ($myid, $fid, $lod, $sid, @P@, @F@, $mynr, $mybranchposition);
+ }
+ state transaction {
+ state run [string map $map $cmd]
+ }
+ }
+ }
+
+ return
+ }
+
+ method DUMP {label} {
+ puts "$label = $self $mytype [$self name] \{"
+ switch -exact -- $mytype {
+ tag {
+ puts "\tR\t$mytagrev"
+ }
+ branch {
+ puts "\tP\t$mybranchparent"
+ puts "\tC\t$mybranchchild"
+ puts "\t\t<$mynr>"
+ }
+ }
+ puts "\}"
+ return
+ }
+
+ # # ## ### ##### ######## #############
+ ## State
+
+ # Persistent:
+ # Tag: myid - tag.tid
+ # myfile - tag.fid
+ # mylod - tag.lod
+ # mysymbol - tag.sid
+ # mytagrev - tag.rev
+ #
+ # Branch: myid - branch.bid
+ # myfile - branch.fid
+ # mylod - branch.lod
+ # mysymbol - branch.sid
+ # mybranchparent - branch.root
+ # mybranchchild - branch.first
+ # mynr - branch.bra
+
+ typevariable myidcounter 0 ; # Counter for symbol ids.
+ variable myid {} ; # Symbol id.
+
+ ## Basic, all symbols _________________
+
+ variable myfile {} ; # Reference to the file the symbol is in.
+ variable mytype {} ; # Symbol type, 'tag', or 'branch'.
+ variable mynr {} ; # Revision number of a 'tag', branch number
+ # of a 'branch'.
+ variable mysymbol {} ; # Reference to the symbol object of this
+ # symbol at the project level.
+ variable mylod {} ; # Reference to the line-of-development
+ # object the symbol belongs to. An
+ # alternative idiom would be to call it the
+ # branch the symbol is on. This reference
+ # is to a project-level object (symbol or
+ # trunk).
+
+ ## Branch symbols _____________________
+
+ variable mybranchparentrevnr {} ; # The number of the parent
+ # revision, derived from our
+ # branch number (mynr).
+ variable mybranchparent {} ; # Reference to the revision
+ # (object) which spawns the
+ # branch.
+ variable mybranchchildrevnr {} ; # Number of the first revision
+ # committed on this branch.
+ variable mybranchchild {} ; # Reference to the revision
+ # (object) first committed on
+ # this branch.
+ variable mybranchposition {} ; # Relative id of the branch in
+ # the file, to sort into
+ # creation order.
+
+ ## Tag symbols ________________________
+
+ variable mytagrev {} ; # Reference to the revision object the tag
+ # is on, identified by 'mynr'.
+
+ # ... nothing special ... (only mynr, see basic)
+
+ # # ## ### ##### ######## #############
+ ## Internal methods
+
+ proc SetupBranch {} {
+ upvar 1 mybranchparentrevnr mybranchparentrevnr mynr mynr
+ set mybranchparentrevnr [rev 2branchparentrevnr $mynr]
+ return
+ }
+
+ # # ## ### ##### ######## #############
+ ## Configuration
+
+ pragma -hastypeinfo no ; # no type introspection
+ pragma -hasinfo no ; # no object introspection
+ pragma -hastypemethods no ; # type is not relevant.
+
+ # # ## ### ##### ######## #############
+}
+
+namespace eval ::vc::fossil::import::cvs::file {
+ namespace export sym
+ namespace eval sym {
+ namespace import ::vc::fossil::import::cvs::file::rev
+ namespace import ::vc::fossil::import::cvs::state
+ namespace import ::vc::fossil::import::cvs::integrity
+ namespace import ::vc::tools::trouble
+ }
+}
+
+# # ## ### ##### ######## ############# #####################
+## Ready
+
+package provide vc::fossil::import::cvs::file::sym 1.0
+return