docstrip_util.tcl

Go to the documentation of this file.
00001 /**  
00002  *# This is the file `docstrip_util.tcl',
00003  *# generated with the SAK utility
00004  *# (sak docstrip/regen).
00005  *# 
00006  *# The original source files were:
00007  *# 
00008  *# tcldocstrip.dtx  (with options: `utilpkg')
00009  *# 
00010  *# In other words:
00011  *# **************************************
00012  *# * This Source is not the True Source *
00013  *# **************************************
00014  *# the true source is the file from which this one was generated.
00015  *#
00016  */
00017 package require Tcl 8.4
00018 package require docstrip 1.2
00019 package provide docstrip::util 1.2
00020 namespace docstrip::util {
00021    namespace import [namespace parent]::extract
00022    namespace export ddt2man guard patch thefile
00023 }
00024 ret  docstrip::util::ddt2man (type text) {
00025    set wascode 0
00026    set verbatim 0
00027    set res ""
00028    foreach line [split $text \n] {
00029       if {$verbatim} then {
00030          if {$line eq $endverbline} then {
00031             set verbatim 0
00032          } else {
00033             append res [string map {[ [lb] ] [rb]} $line] \n
00034          }
00035       } else {
00036          switch -glob -- $line %%* {
00037             if {$wacode} then {
00038                append res {[example_end]} \n
00039                set wascode 0
00040             }
00041             append res [string range $line 2 end] \n
00042          } %<<* {
00043             if {!$wascode} then {
00044                append res {[example_begin]} \n
00045                set wascode 1
00046             }
00047             set endverbline "%[string range $line 3 end]"
00048             set verbatim 1
00049          } %<* {
00050             if {!$wascode} then {
00051                append res {[example_begin]} \n
00052                set wascode 1
00053             }
00054             set guard ""
00055             regexp -- {(^%<[^>]*>)(.*)$} $line "" guard line
00056             append res \[ [list emph $guard] \]\
00057               [string map {[ [lb] ] [rb]} $line] \n
00058          } %* {
00059             if {$wascode} then {
00060                append res {[example_end]} \n
00061                set wascode 0
00062             }
00063             append res [string range $line 1 end] \n
00064          } {\\endinput} {
00065            break
00066          } "" {
00067             append res \n
00068          } default {
00069             if {!$wascode} then {
00070                append res {[example_begin]} \n
00071                set wascode 1
00072             }
00073             append res [string map {[ [lb] ] [rb]} $line] \n
00074          }
00075       }
00076    }
00077    if {$wascode} then {append res {[example_end]} \n}
00078    return $res
00079 }
00080 ret  docstrip::util::guards (type subcmd , type text) {
00081    set verbatim 0
00082    set lineno 1
00083    set badL {}
00084    foreach line [split $text \n] {
00085       if {$verbatim} then {
00086          if {$line eq $endverbline} then {set verbatim 0}
00087       } else {
00088          switch -glob -- $line %<<* {
00089             set endverbline "%[string range $line 3 end]"
00090             set verbatim 1
00091          } %<* {
00092             if {![
00093                regexp -- {^%<([*/+-]?)([^>]*)>(.*)$} $line ""\
00094                  modifier expression line
00095             ]} then {
00096                lappend badL $lineno $line
00097             } else {
00098                if {$modifier eq ""} then {set modifier " "}
00099                append E($expression) $modifier
00100             }
00101          }
00102       }
00103       incr lineno
00104    }
00105    if {$subcmd eq "rotten"} then {return $badL}
00106    switch -- $subcmd "exprmods" {
00107       return [array get E]
00108    } "expressions" {
00109       return [array names E]
00110    } "exprerr" {
00111       set res {}
00112       foreach expr [array names E] {
00113          regsub -all {[^()!,|&]+} $expr 0 e
00114          regsub -all {,} $e {|} e
00115          if {[catch {expr $e}]} then {lappend res $expr}
00116       }
00117       return $res
00118    }
00119    foreach name [array names E] {
00120       set E($name) [string length $E($name)]
00121    }
00122    if {$subcmd eq "exprcounts"} then {return [array get E]}
00123    foreach expr [array names E] {
00124       foreach term [split $expr "()!,|&"] {
00125          if {$term eq ""} then {continue}
00126          if {![info exists T($term)]} then {set T($term) 0}
00127          incr T($term) $E($expr)
00128       }
00129    }
00130    switch -- $subcmd "counts" {
00131       return [array get T]
00132    } "names" {
00133       return [array names T]
00134    } default {
00135       error "Unknown subcommand '$subcmd', must be one of:\
00136         counts, exprcounts, expressions, exprmods, names, rotten"
00137    }
00138 }
00139 ret  docstrip::util::patch (type sourcevar , type termL , type fromtext , type diff , type args) {
00140    upvar 1 $sourcevar SL
00141    array set O {-trimlines 1 -matching exact}
00142    array set O $args
00143    set cmd [list extract [join $SL \n]  $termL -annotate 2]
00144    foreach opt {-metaprefix -trimlines} {
00145       if {[info exists O($opt)]} then {lappend cmd $opt $O($opt)}
00146    }
00147    set EL [split [eval $cmd] \n]
00148    lset EL end \n
00149    set ptr 0
00150    set lineno 1
00151    set FL [list {}]
00152    foreach line [split $fromtext \n] {
00153       lappend FL $line
00154       if {$O(-trimlines)} then {set line [string trimright $line " "]}
00155       if {$line eq [lindex $EL $ptr]} then {
00156          set lift($lineno) [lindex $EL [incr ptr]]
00157          lset lift($lineno) 0 [expr { [lindex $EL [incr ptr]] - 1 }]
00158          incr ptr
00159       }
00160       incr lineno
00161    }
00162    if {![array size lift]} then {
00163       return -code error "The extract did not match any part of the\
00164         fromtext. Check the list of terminals and the options"
00165    }
00166    set RL [list]
00167    set log [list]
00168    foreach hunk [lsort -decreasing -integer -index 0 $diff] {
00169       set replL [list]
00170       set l1 [lindex $hunk 0]
00171       set repl {0 -1}
00172       set matches 1
00173       foreach {type line} [lindex $hunk 4] {
00174          switch -glob -- $type {[0-]} {
00175             switch -- $O(-matching) "exact" {
00176                if {[lindex $FL $l1] ne $line} then {set matches 0}
00177             } "nonspace" {
00178                if {[regsub -all -- {\s} $line {}] ne\
00179                  [regsub -all -- {\s} [lindex $FL $l1] {}]} then {
00180                   set matches 0
00181                }
00182             } "anyspace" {
00183                if {[regsub -all -- {\s+} $line { }] ne\
00184                  [regsub -all -- {\s+} [lindex $FL $l1] { }]} then {
00185                   set matches 0
00186                }
00187             }
00188          }
00189          switch -- $type synch {
00190             if {[llength $repl]>2 ||\
00191               [lindex $repl 1]-[lindex $repl 0]>=0} then {
00192                lappend replL $repl
00193             }
00194             set repl [list $l1 [expr {$l1-1}]]
00195          } + {
00196             lappend repl $line
00197          } - {
00198             lset repl 1 $l1
00199             incr l1
00200          } 0 {
00201             if {[llength $repl]>2 ||\
00202               [lindex $repl 1]-[lindex $repl 0]>=0} then {
00203                lappend replL $repl
00204                set repl {0 -1}
00205             }
00206             lset repl 1 $l1
00207             incr l1
00208             lset repl 0 $l1
00209          }
00210       }
00211       if {[llength $repl]>2 || [lindex $repl 1]-[lindex $repl 0]>=0}\
00212       then {lappend replL $repl}
00213       if {$matches} then {
00214          lappend hunk [lsort -decreasing -integer -index 0 $replL]
00215          lappend RL $hunk
00216       } else {
00217          lappend hunk "(-- did not match fromtext --)"
00218          lappend log $hunk
00219       }
00220    }
00221    foreach hunk $RL {
00222       set applied 0
00223       set misapplied 0
00224       foreach repl [lindex $hunk 5] {
00225          unset -nocomplain from to
00226          for {set n [lindex $repl 1]} {$n>=[lindex $repl 0]}\
00227            {incr n -1} {
00228             if {![info exists lift($n)]} then {
00229                incr misapplied
00230                continue
00231             } elseif {![info exists from]} then {
00232                set to [lindex $lift($n) 0]
00233                set from $to
00234             } elseif {[lindex $lift($n) 0] == $from-1} then {
00235                set from [lindex $lift($n) 0]
00236             } else {
00237                set SL [lreplace $SL $from $to]
00238                set to [lindex $lift($n) 0]
00239                set from $to
00240             }
00241             incr applied
00242             set n0 $n
00243          }
00244          if {[info exists from]} then {
00245             set sprefix [lindex $lift($n0) 1]
00246             set eprefix [lindex $lift($n0) 2]
00247          } elseif {[info exists lift([lindex $repl 0])]} then {
00248             foreach {from sprefix eprefix} $lift([lindex $repl 0])\
00249               break
00250             set to [expr {$from-1}]
00251          } else {
00252             incr misapplied [llength [lrange $repl 2 end]]
00253             continue
00254          }
00255          set eplen [string length $eprefix]
00256          set epend [expr {$eplen-1}]
00257          set cmd [list lreplace $SL $from $to]
00258          foreach line [lrange $repl 2 end] {
00259             if {$eprefix eq [string range $line 0 $epend]} then {
00260                lappend cmd "$sprefix[string range $line $eplen end]"
00261             } else {
00262                lappend cmd $line
00263             }
00264             incr applied
00265          }
00266          set SL [eval $cmd]
00267       }
00268       if {$misapplied>0} then {
00269          if {$applied>0} then {
00270             lset hunk 5 "(-- was partially applied --)"
00271          } else {
00272             lset hunk 5 "(not applied)"
00273          }
00274          lappend log $hunk
00275       }
00276    }
00277    set res ""
00278    foreach hunk [lsort -index 0 -integer $log] {
00279       foreach {start1 end1 start2 end2 lines msg} $hunk break
00280       append res [format "@@ -%d,%d +%d,%d @@ %s\n"\
00281         $start1 [expr {$end1-$start1+1}]\
00282         $start2 [expr {$end2-$start2+1}] $msg]
00283       foreach {type line} $lines {
00284          switch -- $type 0 {
00285             append res " " $line \n
00286          } - - + {
00287             append res $type $line \n
00288          }
00289       }
00290    }
00291    return $res
00292 }
00293 ret  docstrip::util::thefile (type fname , type args) {
00294    set F [open $fname r]
00295    if {[llength $args]} then {
00296       if {[set code [
00297          catch {eval [linsert $args 0 fconfigure $F]} res
00298       ]]} then {
00299          close $F
00300          return -code $code -errorinfo $::errorInfo -errorcode\
00301            $::errorCode
00302       }
00303    }
00304    catch {read $F} res
00305    close $F
00306    return $res
00307 }
00308 ret  docstrip::util::import_unidiff (type text , optional warnvar ="") {
00309    if {$warnvar ne ""} then {upvar 1 $warnvar warning}
00310    set inheader 1
00311    set res [list]
00312    set lines [list]
00313    set end2 "not an integer"
00314    foreach line [split $text \n] {
00315       if {$inheader && [regexp {^(---|\+\+\+)} $line]}\
00316       then {continue}
00317       switch -glob -- $line { *} {
00318          lappend lines 0 [string range $line 1 end]
00319       } {+*} {
00320          lappend lines + [string range $line 1 end]
00321       } {-*} {
00322          lappend lines - [string range $line 1 end]
00323       } @@* {
00324          if {[string is integer $end2]} then {
00325             lappend res [list $start1 $end1 $start2 $end2 $lines]
00326          }
00327          set len2 [set len1 ,1]
00328          if {[
00329             regexp {^@@ -([0-9]+)(,[0-9]+)? \+([0-9]+)(,[0-9]+)? @@}\
00330               $line -> start1 len1 start2 len2
00331          ] && [scan "$start1 $len1,1" {%d ,%d} start1 len1]==2 &&\
00332               [scan "$start2 $len2,1" {%d ,%d} start2 len2]==2
00333          } then {
00334             set end1 [expr {$start1+$len1-1}]
00335             set end2 [expr {$start2+$len2-1}]
00336             set inheader 0
00337          } else {
00338             set end2 "not an integer"
00339             append warning "Could not parse hunk header:  " $line \n
00340          }
00341          set lines [list]
00342       } "" {
00343       } default {
00344          append warning "Could not parse line:  " $line \n
00345       }
00346    }
00347    if {[string is integer $end2]} then {
00348       lappend res [list $start1 $end1 $start2 $end2 $lines]
00349    }
00350    return $res
00351 }
00352 /**  
00353  *# 
00354 ## End of file `docstrip_util.tcl'.

Generated on 21 Sep 2010 for Gui by  doxygen 1.6.1