Version 0 of Wikit run in a Slave Interpreter on TclHttpd

Updated 2004-03-18 05:00:57

WhipIt - Wikit run in a Slave Interpreter on TclHttpd

To try WhipIt place the following whipit.tcl code into the custom directory of your TclHttpd Starkit or get a ready made starkit, whipit.kit, from [L1 ]. Make sure the Wikit Starkit, wikit.kit, is in the same directory as whipit.kit.

To launch on unix

# ./tclkit whipit.kit

On Windows

from a dos window

C:\tclkitsh whipit.kit

from windows explorer

drag and release whipit.kit on tclkit

Point your browser to

http://yourhost:8015/wikit/

************* whipit.tcl ****************************

 #Mount the wikit startkit
 vfs::mk4::Mount [file dir $starkit::topdir]/wikit.kit [file dir $starkit::topdir]/wikit.kit

 set WktDir [file dir $starkit::topdir]/wikit.kit

 # Append wikit library from the mounted wikit starkit to the auto_path
 lappend auto_path [file dir $starkit::topdir]/wikit.kit/lib

 Url_PrefixInstall /wikit [list wikitProc /wikit]

 proc wikitProc {prefix sock suffix} {
         upvar #0 Httpd$sock data
         global env auto_path

      # Set the CGI environment variables

      Cgi_SetEnv $sock $prefix
      set env(PATH_INFO) $suffix
      set env(SCRIPT_NAME) $prefix

      # This sets the WIKIT_BASE environment vaiable dynamically based on
      # the host portion of the url typed in the browser.

      set env(WIKIT_BASE) http://$env(HTTP_HOST)$prefix/

      append data(query) ""

      # Use the Session Module in TclHttpd to create a slave interpreter.
      # A session state array is also created but we don't use it. This
      # maybe of some use if you have a need for a session based wiki.
      #
      # To emulate a CGI environment for Wikit, a slave interpreter is created
      # and then destroyed per request.

      # Destroy any old sessions that are laying around. Interpreters that have
      # been created but for some reason not destroyed. In this instance
      # 2 minutes is the setting.

      Session_Reap 120 Wkt

      # Create a new session.

      set session [Session_Create Wkt 0]

      set html [WktProcess $session $data(query)]

      Httpd_ReturnData $sock text/html $html
      Session_Destroy $session
 }

 proc WktProcess {session query} {
      upvar #0 Session:$session state
      set interp $state(interp)
      global auto_path WktDir

      set WktCGI_LineNumber 0

      set html ""

      # Redirect the read and puts in the slave interpreter
      # that runs Wikit.

      interp eval  $interp {rename puts real_puts}
      interp alias $interp puts {} WktCGI_Puts
      interp hidden $interp
      interp eval $interp {rename read real_read}
      interp alias $interp read {} WktCGI_Read $interp $query

      # Fool wikit to think it is running in it own Starkit so we can copy
      # the first ten pages from wikidoc.tkd

      interp eval $interp [list namespace eval starkit set topdir $WktDir]

      # Following taken from httpd.tcl for getting these variables into
      # a slave interpreter.
      #
      # Transfer the scalar global variables

      foreach var {::v ::auto_path} {
         $interp eval [list set $var [set $var]]
      }

      # Procedure that is run when the slave interpreter does a read.

      proc WktCGI_Read {interp query args} {

            if { [llength $args] == 2 && [lindex $args 0] == "stdin" } {
                return [$interp eval subst $query]
            } else {
                return [$interp eval real_read $args]
            }
      }

      # Precedure that is run when the slave interpreter does a puts.

      proc WktCGI_Puts {args} {
            upvar 1 WktCGI_LineNumber WktCGI_LineNumber
            upvar 1 html html

            incr WktCGI_LineNumber
            if {$WktCGI_LineNumber <= 4} {
                return ""
            } else {
                 append html [lindex $args end]
            }
      }


      # Setup and run Wikit.

      $interp eval {
                    set argv0 tclkit
                    set argv {}
                    set argc 0

                    package require cgi
                    #cgi_debug -on

                    # Work around for getting lassign into the slave interpreter.
                    # From "Practical Programming in Tcl and Tk" Third Edition
                    # by Brent B. Welch page 131.

                    proc lassign {valueList args} {
                         if {[llength $args] == 0 } {
                             error "wrong # args: lassign list varname ?varname ..?"
                         }
                         if {[llength $valueList] == 0} {
                             #Ensure one trip through the foreach loop
                              set valueList [list {}]
                         }
                         uplevel 1 [list foreach $args $valueList {break}]
                         return [lrange $valueList [llength $args] end]
                    }

                    # Source the starkit
                    package require app-wikit
       }
       return $html
 }

**********************************************************************************