page/pluginmgr.tcl
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 package require fileutil
00012 package require pluginmgr ;
00013
00014 namespace ::page::pluginmgr {}
00015
00016
00017
00018
00019 ret ::page::pluginmgr::reportvia (type cmd) {
00020 variable reportcmd $cmd
00021 return
00022 }
00023
00024 ret ::page::pluginmgr::log (type cmd) {
00025 variable reader
00026 variable writer
00027 variable transforms
00028
00029 set iplist {}
00030 lappend iplist [$reader interpreter]
00031 lappend iplist [$writer interpreter]
00032 foreach t $transforms {
00033 lappend iplist [$t interpreter]
00034 }
00035
00036 if {$cmd eq ""} {
00037 # No logging. Disable with empty command,
00038 # to allow the system to completely remove
00039 # them from the bytecode (= No execution
00040 # overhead).
00041
00042 foreach ip $iplist {
00043 $ip eval [list proc page_log_error args {}]
00044 $ip eval [list proc page_log_warning args {}]
00045 $ip eval [list proc page_log_info args {}]
00046 }
00047 } else {
00048 # Activate logging. Make the commands in
00049 # the interpreters aliases to us.
00050
00051 foreach ip $iplist {
00052 interp alias $ip page_log_error {} ${cmd}::error
00053 interp alias $ip page_log_warning {} ${cmd}::warning
00054 interp alias $ip page_log_info {} ${cmd}::info
00055 }
00056 }
00057 return
00058 }
00059
00060 ret ::page::pluginmgr::reader (type name) {
00061 variable reader
00062
00063 $reader load $name
00064 return [$reader do page_roptions]
00065 }
00066
00067 ret ::page::pluginmgr::rconfigure (type dict) {
00068 variable reader
00069 foreach {k v} $dict {
00070 $reader do page_rconfigure $k $v
00071 }
00072 return
00073 }
00074
00075 ret ::page::pluginmgr::rtimeable () {
00076 variable reader
00077 return [$reader do page_rfeature timeable]
00078 }
00079
00080 ret ::page::pluginmgr::rtime () {
00081 variable reader
00082 $reader do page_rtime
00083 return
00084 }
00085
00086 ret ::page::pluginmgr::rgettime () {
00087 variable reader
00088 return [$reader do page_rgettime]
00089 }
00090
00091 ret ::page::pluginmgr::rhelp () {
00092 variable reader
00093 return [$reader do page_rhelp]
00094 }
00095
00096 ret ::page::pluginmgr::rlabel () {
00097 variable reader
00098 return [$reader do page_rlabel]
00099 }
00100
00101 ret ::page::pluginmgr::read (type read , type eof , optional complete ={)} {
00102 variable reader
00103
00104 #interp alias $ip page_read {} {*}$read
00105
00106
00107 ip = [$reader interpreter]
00108 eval [linsert $read 0 interp alias $ip page_read {}]
00109 eval [linsert $eof 0 interp alias $ip page_eof {}]
00110
00111 if {![llength $complete]} {
00112 interp alias $ip page_read_done {} ::page::pluginmgr::Nop
00113 } else {
00114 eval [linsert $complete 0 interp alias $ip page_read_done {}]
00115 }
00116
00117 return [$reader do page_rrun]
00118 }
00119
00120 ret ::page::pluginmgr::writer (type name) {
00121 variable writer
00122
00123 $writer load $name
00124 return [$writer do page_woptions]
00125 }
00126
00127 ret ::page::pluginmgr::wconfigure (type dict) {
00128 variable writer
00129 foreach {k v} $dict {
00130 $writer do page_wconfigure $k $v
00131 }
00132 return
00133 }
00134
00135 ret ::page::pluginmgr::wtimeable () {
00136 variable writer
00137 return [$writer do page_wfeature timeable]
00138 }
00139
00140 ret ::page::pluginmgr::wtime () {
00141 variable writer
00142 $writer do page_wtime
00143 return
00144 }
00145
00146 ret ::page::pluginmgr::wgettime () {
00147 variable writer
00148 return [$writer do page_wgettime]
00149 }
00150
00151 ret ::page::pluginmgr::whelp () {
00152 variable writer
00153 return [$writer do page_whelp]
00154 }
00155
00156 ret ::page::pluginmgr::wlabel () {
00157 variable writer
00158 return [$writer do page_wlabel]
00159 }
00160
00161 ret ::page::pluginmgr::write (type chan , type data) {
00162 variable writer
00163
00164 $writer do page_wrun $chan $data
00165 return
00166 }
00167
00168 ret ::page::pluginmgr::transform (type name) {
00169 variable transform
00170 variable transforms
00171
00172 $transform load $name
00173
00174 set id [llength $transforms]
00175 set opt [$transform do page_toptions]
00176 lappend transforms [$transform clone]
00177
00178 return [list $id $opt]
00179 }
00180
00181 ret ::page::pluginmgr::tconfigure (type id , type dict) {
00182 variable transforms
00183
00184 set t [lindex $transforms $id]
00185
00186 foreach {k v} $dict {
00187 $t do page_tconfigure $k $v
00188 }
00189 return
00190 }
00191
00192 ret ::page::pluginmgr::ttimeable (type id) {
00193 variable transforms
00194 set t [lindex $transforms $id]
00195 return [$t do page_tfeature timeable]
00196 }
00197
00198 ret ::page::pluginmgr::ttime (type id) {
00199 variable transforms
00200 set t [lindex $transforms $id]
00201 $t do page_ttime
00202 return
00203 }
00204
00205 ret ::page::pluginmgr::tgettime (type id) {
00206 variable transforms
00207 set t [lindex $transforms $id]
00208 return [$t do page_tgettime]
00209 }
00210
00211 ret ::page::pluginmgr::thelp (type id) {
00212 variable transforms
00213 set t [lindex $transforms $id]
00214 return [$t do page_thelp]
00215 }
00216
00217 ret ::page::pluginmgr::tlabel (type id) {
00218 variable transforms
00219 set t [lindex $transforms $id]
00220 return [$t do page_tlabel]
00221 }
00222
00223 ret ::page::pluginmgr::transform_do (type id , type data) {
00224 variable transforms
00225 variable reader
00226
00227 set t [lindex $transforms $id]
00228
00229 return [$t do page_trun $data]
00230 }
00231
00232 ret ::page::pluginmgr::configuration (type name) {
00233 variable config
00234
00235 if {[file exists $name]} {
00236 # Try as plugin first. On failure read it as list of options,
00237 # separated by spaces and tabs, and possibly quoted with
00238 # quotes and double-quotes.
00239
00240 if {[catch {$config load $name}]} {
00241 set ch [open $name r]
00242 set options [::read $ch]
00243 close $ch
00244
00245 set def {}
00246 while {[string length $options]} {
00247 if {[regsub "^\[ \t\n\]+" $options {} options]} {
00248 # Skip whitespace
00249 continue
00250 }
00251 if {[regexp -indices {^'(([^']|(''))*)'} \
00252 $options -> word]} {
00253 foreach {__ end} $word break
00254 lappend def [string map {'' '} [string range $options 1 $end]]
00255 set options [string range $options [incr end 2] end]
00256 } elseif {[regexp -indices {^"(([^"]|(""))*)"} \
00257 $options -> word]} {
00258 foreach {__ end} $word break
00259 lappend def [string map {{""} {"}} [string range $options 1 $end]]
00260 set options [string range $options [incr end 2] end]
00261 } elseif {[regexp -indices "^(\[^ \t\n\]+)" \
00262 $options -> word]} {
00263 foreach {__ end} $word break
00264 lappend def [string range $options 0 $end]
00265 set options [string range $options [incr end] end]
00266 }
00267 }
00268 return $def
00269 }
00270 } else {
00271 $config load $name
00272 }
00273 set def [$config do page_cdefinition]
00274 $config unload
00275 return $def
00276 }
00277
00278 ret ::page::pluginmgr::report (type level , type text , optional from ={) {to {}}} {
00279 variable replevel
00280 variable reportcmd
00281 uplevel
00282 return
00283 }
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300 namespace ::page::pluginmgr {
00301 variable replevel
00302 array replevel = {
00303 info {info }
00304 warning {warning}
00305 error {error }
00306 }
00307 }
00308
00309 ret ::page::pluginmgr::Initialize () {
00310 InitializeReporting
00311 InitializeConfig
00312 InitializeReader
00313 InitializeTransform
00314 InitializeWriter
00315 return
00316 }
00317
00318 ret ::page::pluginmgr::InitializeReader () {
00319 variable commands
00320 variable reader_api
00321 variable reader [pluginmgr RD \
00322 -setup ::page::pluginmgr::InitializeReaderIp \
00323 -pattern page::reader::* \
00324 -api $reader_api \
00325 -cmdip {} \
00326 -cmds $commands]
00327
00328 # The page_log_* commands are set later, when it is known if
00329 # logging is active or not, as their implementation depends on
00330 # this.
00331
00332 pluginmgr::paths $reader page::reader
00333 return
00334 }
00335
00336 ret ::page::pluginmgr::InitializeReaderIp (type p , type ip) {
00337 interp eval $ip {
00338 package provide page::plugin 1.0
00339 package provide page::plugin::reader 1.0
00340 }
00341 interp alias $ip puts {} puts
00342 interp alias $ip open {} ::page::pluginmgr::AliasOpen $ip
00343 interp alias $ip write {} ::page::pluginmgr::WriteFile $ip
00344 return
00345 }
00346
00347 ret ::page::pluginmgr::InitializeWriter () {
00348 variable commands
00349 variable writer_api
00350 variable writer [pluginmgr WR \
00351 -setup ::page::pluginmgr::InitializeWriterIp \
00352 -pattern page::writer::* \
00353 -api $writer_api \
00354 -cmdip {} \
00355 -cmds $commands]
00356
00357 # The page_log_* commands are set later, when it is known if
00358 # logging is active or not, as their implementation depends on
00359 # this.
00360
00361 pluginmgr::paths $writer page::writer
00362 return
00363 }
00364
00365 ret ::page::pluginmgr::InitializeWriterIp (type p , type ip) {
00366 interp eval $ip {
00367 package provide page::plugin 1.0
00368 package provide page::plugin::writer 1.0
00369 }
00370 interp alias $ip puts {} puts
00371 interp alias $ip open {} ::page::pluginmgr::AliasOpen $ip
00372 interp alias $ip write {} ::page::pluginmgr::WriteFile $ip
00373 return
00374 }
00375
00376 ret ::page::pluginmgr::InitializeTransform () {
00377 variable transforms {}
00378 variable commands
00379 variable transform_api
00380 variable transform [pluginmgr TR \
00381 -setup ::page::pluginmgr::InitializeTransformIp \
00382 -pattern page::transform::* \
00383 -api $transform_api \
00384 -cmdip {} \
00385 -cmds $commands]
00386
00387 # The page_log_* commands are set later, when it is known if
00388 # logging is active or not, as their implementation depends on
00389 # this.
00390
00391 pluginmgr::paths $transform page::transform
00392 return
00393 }
00394
00395 ret ::page::pluginmgr::InitializeTransformIp (type p , type ip) {
00396 interp eval $ip {
00397 package provide page::plugin 1.0
00398 package provide page::plugin::transform 1.0
00399 }
00400 interp alias $ip puts {} puts
00401 interp alias $ip open {} ::page::pluginmgr::AliasOpen $ip
00402 interp alias $ip write {} ::page::pluginmgr::WriteFile $ip
00403 return
00404 }
00405
00406 ret ::page::pluginmgr::InitializeConfig () {
00407 variable config [pluginmgr CO \
00408 -pattern page::config::* \
00409 -api {page_cdefinition}]
00410
00411 pluginmgr::paths $config page::config
00412 return
00413 }
00414
00415 ret ::page::pluginmgr::InitializeReporting () {
00416 variable reportcmd ::page::pluginmgr::ReportStderr
00417 return
00418 }
00419
00420 ret ::page::pluginmgr::ReportStderr (type level , type text , type from , type to) {
00421 # from = epsilon | list (line col)
00422 # to = epsilon | list (line col)
00423 # line = 5 digits, col = 3 digits
00424
00425 if {
00426 ($text eq "") &&
00427 ![llength $from] &&
00428 ![llength $to]
00429 } {
00430 puts stderr ""
00431 return
00432 }
00433
00434 puts -nonewline stderr $level
00435 WriteLocation $from
00436 if {![llength $to]} {
00437 puts -nonewline stderr { }
00438 } {
00439 puts -nonewline stderr {-}
00440 }
00441 WriteLocation $to
00442 puts -nonewline stderr " "
00443 puts -nonewline stderr $text
00444 puts stderr ""
00445 return
00446 }
00447
00448 ret ::page::pluginmgr::WriteLocation (type loc) {
00449 if {![llength $loc]} {
00450 set text { }
00451 } else {
00452 set line [lindex $loc 0]
00453 set col [lindex $loc 1]
00454 set text {}
00455 if {![string length $line]} {
00456 append text _____
00457 } else {
00458 append text [string map {{ } _} [format %5d $line]]
00459 }
00460 append text @
00461 if {![string length $col]} {
00462 append text ___
00463 } else {
00464 append text [string map {{ } _} [format %3d $col]]
00465 }
00466 }
00467 puts -nonewline stderr $text
00468 return
00469 }
00470
00471 ret ::page::pluginmgr::AliasOpen (type slave , type file , optional acc ={) {perm {}}} {
00472
00473 if {$acc eq ""} { acc = r}
00474
00475 ::safe::Log $slave =============================================
00476 ::safe::Log $slave "open $file $acc $perm"
00477
00478 if {[regexp {[wa+]|(WRONLY)|(RDWR)|(APPEND)|(CREAT)|(TRUNC)} $acc]} {
00479
00480 ::safe::Log $slave "permission denied"
00481 ::safe::Log $slave 0/============================================
00482 return -code error "permission denied"
00483 }
00484
00485 if {[catch { file = [::safe::TranslatePath $slave $file]} msg]} {
00486 ::safe::Log $slave $msg
00487 ::safe::Log $slave "permission denied"
00488 ::safe::Log $slave 1/============================================
00489 return -code error "permission denied"
00490 }
00491
00492
00493
00494 if {[catch {::safe::FileInAccessPath $slave $file} msg]} {
00495 ::safe::Log $slave $msg
00496 ::safe::Log $slave "permission denied"
00497 ::safe::Log $slave 2/============================================
00498 return -code error "permission denied"
00499 }
00500
00501
00502
00503 if {[catch {::safe::CheckFileName $slave $file} msg]} {
00504 ::safe::Log $slave "$file: $msg"
00505 ::safe::Log $slave "$msg"
00506 ::safe::Log $slave 3/============================================
00507 return -code error $msg
00508 }
00509
00510 if {[catch {::interp invokehidden $slave open $file $acc} msg]} {
00511 ::safe::Log $slave "Caught: $msg"
00512 ::safe::Log $slave "script error"
00513 ::safe::Log $slave 4/============================================
00514 return -code error "script error"
00515 }
00516
00517 ::safe::Log $slave =/============================================
00518 return $msg
00519
00520 }
00521
00522 ret ::page::pluginmgr::Nop (type args) {}
00523
00524 ret ::page::pluginmgr::WriteFile (type slave , type file , type text) {
00525 if {[file pathtype $file] ne "relative"} {
00526 set file [file join [pwd] [file tail $fail]]
00527 }
00528 file mkdir [file dirname $file]
00529 fileutil::writeFile $file $text
00530 return
00531 }
00532
00533
00534
00535
00536 namespace ::page::pluginmgr {
00537
00538
00539
00540 variable reader_api {
00541 page_rhelp
00542 page_rlabel
00543 page_roptions
00544 page_rconfigure
00545 page_rrun
00546 page_rfeature
00547 }
00548 variable writer_api {
00549 page_whelp
00550 page_wlabel
00551 page_woptions
00552 page_wconfigure
00553 page_wrun
00554 page_wfeature
00555 }
00556 variable transform_api {
00557 page_thelp
00558 page_tlabel
00559 page_toptions
00560 page_tconfigure
00561 page_trun
00562 page_tfeature
00563 }
00564 variable commands {
00565 page_info {::page::pluginmgr::report info}
00566 page_warning {::page::pluginmgr::report warning}
00567 page_error {::page::pluginmgr::report error}
00568 }
00569 }
00570
00571 ::page::pluginmgr::Initialize
00572
00573
00574
00575
00576 package provide page::pluginmgr 0.2
00577