A quickie to apply patches generated by [diff] -n (so-called rcs format) - [CMcC] 20041006 ====== # patch a file given diffs in rcs (diff -n) format package require fileutil namespace eval rcs {} # convert \n delimited file to an array indexed by line name proc rcs::file2array {filename arr} { upvar 1 $arr lines set lnum 0 fileutil::foreachLine line $filename { set lines([incr lnum]) $line } } # convert \n delimited text to an array indexed by line name proc rcs::text2array {text arr} { upvar 1 $arr lines set lnum 0 foreach line [split $text \n] { set lines([incr lnum]) $line } } # Apply some rcs diff -n format patches to the text in array proc rcs::patch {patch arr} { upvar 1 $arr lines set patch [split $patch \n] while {$patch != {}} { set pc [string trim [lindex $patch 0]] puts stderr "doing $pc" set patch [lrange $patch 1 end] switch -glob -- $pc { "" {} a* { foreach {start len} [split [string range $pc 1 end]] break set adding [join [lrange $patch 0 [expr {$len - 1}]] \n] if {[info exists lines($start)]} { append lines($start) \n } append lines($start) "$adding" puts stderr "ADD: '$adding'" set patch [lrange $patch $len end] puts stderr "$pc: $lines($start)" } d* { foreach {start len} [split [string range $pc 1 end]] break while {$len > 0} { puts stderr "DEL $start: $lines($start)" unset lines($start) incr start incr len -1 } } default { error "Unknown patch: '$pc'" } } } set result "" foreach lnum [lsort -integer [array names lines]] { append result \n $lines($lnum) } return [string range $result 1 end] } ======