📄 isip_tkdiff.tcl
字号:
close $fp $p.t configure -state disabled}# method: rescan## repeat the file scan in case external changes were made#proc rescan {} { global file1 file2 cvs_mode jump_pos p if [string match $file2 ""] { viewFile $file1 } else { set old_jump_pos $jump_pos if {$cvs_mode} { scanFileCvs $file1 } else { scanFile $file1 $file2 } set jump_line [expr [lindex [split $old_jump_pos "."] 0] -1] set jp "$jump_line.0" # find the previous modified tag # set next_range [$p.t tag nextrange modified $jp] jumpAndShowChange $p.t $next_range }}# method: closeOrExit## if in file mode, just quit. If in directory mode, kill the file text# viewer and raise the directory viewer#proc closeOrExit {} { global pd p if [string match $pd ".pdir"] { wm iconify $p raise $pd } else { cleanExit }}# method: cleanExit## clean up temp files and exit#proc cleanExit {} { global temp_files catch { eval "exec rm -fr [join $temp_files]" } exit}# method: getModuleNameCvs## get the cvs module name#proc getModuleNameCvs {dir} { set rep [getRepositoryNameCvs $dir] global env if {! [file isdirectory $dir]} { puts "Error: $dir not a directory" exit } # first try to just use CVSROOT # set root "" catch {set root $env(CVSROOT)} # if CVSROOT is not set, then read out of the Root file # if [string match $root ""] { set root_file "$dir/CVS/Root" if {! [file exists $root_file]} { puts "Error: cannot read $root_file" exit } set fp [open $root_file "r"] set root [gets $fp] close $fp } # make sure that the repository is based on the root # if {[string first $root $rep] == 0} { # pull the root from the repository location to obtain the module # set module [string range $rep [expr [string length $root]+1] end] } else { set module $rep } return $module}# method: getRepositoryNameCvs## get the cvs repository name#proc getRepositoryNameCvs {dir1} { global env if {! [string match [file type $dir1] "directory"]} { puts "Error: $dir1 not a directory" exit } # the repository file contains the name of the module with CVSROOT # prepended. open the file and read the string # set rep_file "$dir1/CVS/Repository" if {! [file exists $rep_file]} { puts "Error: cannot read $rep_file" exit } set fp [open $rep_file "r"] set rep [gets $fp] close $fp return $rep}# method: getWorkingDateCvs## get the date from which this cvs version was based#proc getWorkingDateCvs {file1} { if [string match [file type $file1] "file"] { set dir_mode 0 } elseif [string match [file type $file1] "directory"] { set dir_mode 1 set dates {} } else { puts "Error: invalid file type for $file1" exit } set fp [open "| cvs status -l $file1" "r"] while {! [eof $fp]} { set str [gets $fp] if [regexp {Working revision:\s+[\d\.]+\s*(.*)$} $str dummy vdate] { if {$dir_mode == 0} { catch {close $fp} return $vdate } else { lappend dates $vdate } } } catch {close $fp} if {$dir_mode == 1} { set sdate [lsort -decreasing -command cvsDateSort $dates] set vdate [lindex $sdate 0] return $vdate } puts "Error: could not determine version for $file1" exit} # method: cvsDateSort#proc cvsDateSort {date1 date2} { # easy and likely case first # if [string match $date1 $date2] { return 0 } set month(Jan) 0 set month(Feb) 1 set month(Mar) 2 set month(Apr) 3 set month(May) 4 set month(Jun) 5 set month(Jul) 6 set month(Aug) 7 set month(Sep) 8 set month(Oct) 9 set month(Nov) 10 set month(Dec) 11 # match Tue Aug 29 18:41:12 2000 set date_pattern {^\w\w\w\s+(\w\w\w)\s+(\d+)\s+(\d+):(\d+):(\d+)\s+(\d+)$} if {! [regexp $date_pattern $date1 dummy mon1 day1 h1 m1 s1 year1]} { puts "Error: bad date $date1" return 0 } if {! [regexp $date_pattern $date2 dummy mon2 day2 h2 m2 s2 year2]} { puts "Error: bad date $date2" return 0 } if {$year1 > $year2} { return 1 } elseif {$year1 < $year2} { return -1 } else { if {$month($mon1) > $month($mon2)} { return 1 } elseif {$month($mon1) < $month($mon2)} { return -1 } else { if {$day1 > $day2} { return 1 } elseif {$day1 < $day2} { return -1 } else { if {$h1 > $h2} { return 1 } elseif {$h1 < $h2} { return -1 } else { if {$m1 > $m2} { return 1 } elseif {$m1 < $m2} { return -1 } else { if {$s1 > $s2} { return 1 } elseif {$s1 < $s2} { return -1 } else { puts "Error: bad case" exit } } } } } }} # method: scanFileCvs#proc scanFileCvs {f1} { global v_opts p diff_opts file1 file2 v_flag view_title cvs_mode cvs set cvs_mode 1 set file2 "" # make sure both arguments are files # if [file isdirectory $f1] { mesgBox "tkdiff error" "Error: cannot view directory with file viewer" destroyWin $p return } if {! [file readable $f1]} { mesgBox "tkdiff error" "Error: cannot read $f1" destroyWin $p return } set view_title "tkdiff $f1 [join $v_opts]" displayText set file1 $f1 # first determine the full module and filename # set full_name "[getModuleNameCvs [file dirname $f1]]/[file tail $f1]" # the basis file (the one to which changes are applied) is either # the current version, if no v_opts are specified, or the first # option on the command line. # if {[llength $v_opts] == 0} { set com "$cvs checkout -p $full_name" } else { set com "$cvs checkout -p [lindex $v_opts 0] $full_name" } set fp [open "| $com 2>/dev/null" "r"] $p.t configure -state normal loadFile $p.t $fp close $fp # puts "| $cvs diff $diff_opts [join $v_opts] $file1" # the diff stream will come from cvs diff, not system diff # set fp [open "| $cvs diff $diff_opts [join $v_opts] $file1" "r"] # jump through the CVS stuff until we get to a diff line, if there # is no output it means the file was not changed # set found_diff 0 while {! [eof $fp]} { set str [gets $fp] # is this the diff line? # if [regexp "^diff " $str] {# puts $str set found_diff 1 break } } applyDiff $p.t $fp catch {close $fp} if {[winfo exists $p] == 1} { $p.t configure -state disabled }}# method: scanFileRcs#proc scanFileRcs {file1} { global v_opts temp_files view_title v_flag set file_tail [file tail $file1] set f2 $file1 set f1 "/tmp/tkdiff_[pid]_$file_tail" catch { eval "exec co -p $file1 > $f1" } lappend temp_files $f1 set view_title "tkdiff $file_tail ([lindex $v_opts 0] vs local)" scanFile $f1 $f2}# method: scanDir#proc scanDir {dir1 dir2} { global pd v_flag dir_commands displayDir catch {unset dir_commands} set state 0 $pd.d.lb delete 0 end $pd.a.lb delete 0 end $pd.m.lb delete 0 end set fp [open "| diff $dir1 $dir2" "r"] while {! [eof $fp]} { set str [gets $fp] set sstr [split $str] set f1 "" set f2 "" # is a file only in one directory? # if [regexp "^Only in " $str] { set odir [lindex $sstr 2] set ofile [lindex $sstr 3] set odir [string range $odir 0 [expr [string length $odir] -2]] if [string match [file type $odir/$ofile] "directory"] { continue } if [string match "$odir" "$dir1"] { $pd.d.lb insert end "$ofile" set dir_commands($ofile) "viewFile $dir1/$ofile" } elseif [string match "$odir" "$dir2"] { $pd.a.lb insert end "$ofile" set dir_commands($ofile) "viewFile $dir2/$ofile" } else { puts "Error: $str" exit } } elseif [regexp "^diff " $str] { set f1 [file tail [lindex $sstr 1]] if [string match [file type "$dir1/$f1"] "directory"] { continue } $pd.m.lb insert end "$f1" set dir_commands($f1) "scanFile $dir1/$f1 $dir2/$f1" } } catch { close $fp }}# method: scanDirCvs## this method runs cvs diff in directory mode to determine what files# have changed. it will create a list of such files, the user can then# select any one file to have its differences displayed. #proc scanDirCvs {dir1} { global v_opts temp_files v_flag view_title debug pd v_flag dir_commands global cvs displayDir catch {unset dir_commands} set state 0 $pd.d.lb delete 0 end $pd.a.lb delete 0 end $pd.m.lb delete 0 end set fp [open "| $cvs diff [join $v_opts] $dir1 2>/dev/null" "r"] while {! [eof $fp]} { set str [gets $fp] set sstr [split $str] set f1 "" set f2 "" # has something been removed? # if [regexp "^cvs diff: cannot find" $str] { set del_file [lindex $sstr 4] $pd.d.lb insert end "$del_file" puts "del_file = $del_file" set dir_commands($del_file) "viewFileRcs $del_file" } elseif [regexp "^Index: " $str] { set mod_file [lindex $sstr 1] $pd.m.lb insert end "$mod_file" set dir_commands($mod_file) "scanFileCvs $mod_file" } } catch { close $fp }} # method: helpGeneral#proc helpGeneral {} { global env ph displayHelp set fp [open "$env(ISIP_DEVEL)/util/devel/tkdiff/help.txt"] loadFile $ph.t $fp close $fp }# method: destroyWin## kill the specified window. if no windows are left, exit#proc destroyWin {arg} { destroy $arg if {[llength [winfo children .]] == 0} { cleanExit }}# call the main program to parse the command line and run the# appropriate method#main## end of file
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -