[ Avaa Bypassed ]




Upload:

Command:

hmhc3928@18.191.233.251: ~ $
#
# help.tcl --
#
# Tcl help command. (see TclX manual)
# 
#------------------------------------------------------------------------------
# Copyright 1992-1999 Karl Lehenbauer and Mark Diekhans.
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted, provided
# that the above copyright notice appear in all copies.  Karl Lehenbauer and
# Mark Diekhans make no representations about the suitability of this
# software for any purpose.  It is provided "as is" without express or
# implied warranty.
#------------------------------------------------------------------------------
# The help facility is based on a hierarchical tree of subjects (directories)
# and help pages (files).  There is a virtual root to this tree. The root
# being the merger of all "help" directories found along the $auto_path
# variable.
#------------------------------------------------------------------------------
# $Id: help.tcl,v 1.2 2004/11/23 05:54:15 hobbs Exp $
#------------------------------------------------------------------------------
#

#@package: TclX-help help helpcd helppwd apropos

namespace eval ::tclx {
    namespace export help helpcd helppwd apropos
}

namespace eval ::tclx::help {
    variable curSubject "/"
}

#------------------------------------------------------------------------------
# Help command.

proc ::tclx::help {{what {}}} {
    variable ::tclx::help::lineCnt 0

    # Special case "help help", so we can get it at any level.

    if {($what == "help") || ($what == "?")} {
        tclx::help::HelpOnHelp
        return
    }

    set pathList [tclx::help::ConvertPath $what]
    if {[file isfile [lindex $pathList 0]]} {
        tclx::help::DisplayPage [lindex $pathList 0]
        return
    }

    tclx::help::ListSubject $what $pathList subjects pages
    set relativeDir [tclx::help::RelativePath [lindex $pathList 0]]

    if {[llength $subjects] != 0} {
        tclx::help::Display "\nSubjects available in $relativeDir:"
        tclx::help::DisplayColumns $subjects
    }
    if {[llength $pages] != 0} {
        tclx::help::Display "\nHelp pages available in $relativeDir:"
        tclx::help::DisplayColumns $pages
    }
}


#------------------------------------------------------------------------------
# helpcd command.  The name of the new current directory is assembled from the
# current directory and the argument.

proc ::tclx::helpcd {{dir /}} {
    variable ::tclx::help::curSubject

    set pathName [lindex [tclx::help::ConvertPath $dir] 0]

    if {![file isdirectory $pathName]} {
        error "\"$dir\" is not a subject" [list TCLXHELP NOTSUBJECT $dir]
    }

    set ::tclx::help::curSubject [tclx::help::RelativePath $pathName]
    return
}

#------------------------------------------------------------------------------
# Helpcd main.

proc ::tclx::helppwd {} {
    variable ::tclx::help::curSubject
    echo "Current help subject: $::tclx::help::curSubject"
}

#------------------------------------------------------------------------------
# apropos command.  This search the 

proc ::tclx::apropos {regexp} {
    variable ::tclx::help::lineCnt 0
    variable ::tclx::help::curSubject

    set ch [scancontext create]
    scanmatch -nocase $ch $regexp {
        set path [lindex $matchInfo(line) 0]
        set desc [lrange $matchInfo(line) 1 end]
        if {![tclx::help::Display [format "%s - %s" $path $desc]]} {
            set stop 1
            return
	}
    }
    set stop 0
    foreach dir [tclx::help::RootDirs] {
        foreach brief [glob -nocomplain $dir/*.brf] {
            set briefFH [open $brief]
            try_eval {
                scanfile $ch $briefFH
            } {} {
                close $briefFH
            }
            if {$stop} break
        }
        if {$stop} break
    }
    scancontext delete $ch
}

##
## Private Helper Routines
##

#----------------------------------------------------------------------
# Return a list of help root directories.

proc ::tclx::help::RootDirs {} {
    global auto_path
    set roots {}
    foreach dir $auto_path {
	if {[file isdirectory $dir/help]} {
	    lappend roots $dir/help
	}
    }
    return $roots
}

#--------------------------------------------------------------------------
# Take a path name which might have "." and ".." elements and flatten them
# out.  Also removes trailing and adjacent "/", unless its the only
# character.

proc ::tclx::help::FlattenPath pathName {
    set newPath {}
    foreach element [split $pathName /] {
	if {"$element" == "." || [lempty $element]} continue

	if {"$element" == ".."} {
	    if {[llength [join $newPath /]] == 0} {
		error "Help: name goes above subject directory root" {} \
		    [list TCLXHELP NAMEABOVEROOT $pathName]
	    }
	    lvarpop newPath [expr [llength $newPath]-1]
	    continue
	}
	lappend newPath $element
    }
    set newPath [join $newPath /]

    # Take care of the case where we started with something line "/" or "/."

    if {("$newPath" == "") && [string match "/*" $pathName]} {
	set newPath "/"
    }

    return $newPath
}

#--------------------------------------------------------------------------
# Given a pathName relative to the virtual help root, convert it to a list
# of real file paths.  A list is returned because the path could be "/",
# returning a list of all roots. The list is returned in the same order of
# the auto_path variable. If path does not start with a "/", it is take as
# relative to the current help subject.  Note: The root directory part of
# the name is not flattened.  This lets other commands pick out the part
# relative to the one of the root directories.

proc ::tclx::help::ConvertPath pathName {
    variable curSubject

    if {![string match "/*" $pathName]} {
	if {[cequal $curSubject "/"]} {
	    set pathName "/$pathName"
	} else {
	    set pathName "$curSubject/$pathName"
	}
    }
    set pathName [FlattenPath $pathName]

    # If the virtual root is specified, return a list of directories.

    if {$pathName == "/"} {
	return [RootDirs]
    }

    # Not the virtual root find the first match.

    foreach dir [RootDirs] {
	if {[file readable $dir/$pathName]} {
	    return [list $dir/$pathName]
	}
    }

    # Not found, try to find a file matching only the file tail,
    # for example if --> <helpDir>/tcl/control/if.

    set fileTail [file tail $pathName]
    foreach dir [RootDirs] {
	set fileName [exec find $dir -name $fileTail | head -1]
	if {$fileName != {}} {
	    return [list $fileName]
	}
    }

    error "\"$pathName\" does not exist" {} \
	[list TCLXHELP NOEXIST $pathName]
}

#--------------------------------------------------------------------------
# Return the virtual root relative name of the file given its absolute
# path.  The root part of the path should not have been flattened, as we
# would not be able to match it.

proc ::tclx::help::RelativePath pathName {
    foreach dir [RootDirs] {
	if {[csubstr $pathName 0 [clength $dir]] == $dir} {
	    set name [csubstr $pathName [clength $dir] end]
	    if {$name == ""} {set name /}
	    return $name
	}
    }
    if {![info exists found]} {
	error "problem translating \"$pathName\"" {} [list TCLXHELP INTERROR]
    }
}

#--------------------------------------------------------------------------
# Given a list of path names to subjects generated by ConvertPath, return
# the contents of the subjects.  Two lists are returned, subjects under
# that subject and a list of pages under the subject.  Both lists are
# returned sorted.  This merges all the roots into a virtual root.
# pathName is the string that was passed to ConvertPath and is used for
# error reporting.  *.brk files are not returned.

proc ::tclx::help::ListSubject {pathName pathList subjectsVar pagesVar} {
    upvar $subjectsVar subjects $pagesVar pages

    set subjects {}
    set pages {}
    set foundDir 0
    foreach dir $pathList {
	if {![file isdirectory $dir] || [cequal [file tail $dir] CVS]} continue
	set foundDir 1
	foreach file [glob -nocomplain $dir/*] {
	    if {[lsearch {.brf .orig .diff .rej} [file extension $file]] \
		    >= 0} continue
	    if [file isdirectory $file] {
		lappend subjects [file tail $file]/
	    } else {
		lappend pages [file tail $file]
	    }
	}
    }
    if {!$foundDir} {
	if {[cequal $pathName /]} {
	    global auto_path
	    error "no \"help\" directories found on auto_path ($auto_path)" {} \
		[list TCLXHELP NOHELPDIRS]
	} else {
	    error "\"$pathName\" is not a subject" {} \
		[list TCLXHELP NOTSUBJECT $pathName]
	}
    }
    set subjects [lsort $subjects]
    set pages [lsort $pages]
    return {}
}

#--------------------------------------------------------------------------
# Display a line of output, pausing waiting for input before displaying if
# the screen size has been reached.  Return 1 if output is to continue,
# return 0 if no more should be outputed, indicated by input other than
# return.
#

proc ::tclx::help::Display line {
    variable lineCnt
    if {$lineCnt >= 23} {
	set lineCnt 0
	puts -nonewline stdout ":"
	flush stdout
	gets stdin response
	if {![lempty $response]} {
	    return 0}
    }
    puts stdout $line
    incr lineCnt
}

#--------------------------------------------------------------------------
# Display a help page (file).

proc ::tclx::help::DisplayPage filePath {

    set inFH [open $filePath r]
    try_eval {
	while {[gets $inFH fileBuf] >= 0} {
	    if {![Display $fileBuf]} {
		break
	    }
	}
    } {} {
	close $inFH
    }
}

#--------------------------------------------------------------------------
# Display a list of file names in a column format. This use columns of 14 
# characters 3 blanks.

proc ::tclx::help::DisplayColumns {nameList} {
    set count 0
    set outLine ""
    foreach name $nameList {
	if {$count == 0} {
	    append outLine "   "
	}
	append outLine $name
	if {[incr count] < 4} {
	    set padLen [expr 17-[clength $name]]
	    if {$padLen < 3} {
		set padLen 3}
	    append outLine [replicate " " $padLen]
	} else {
	    if {![Display $outLine]} {
		return}
	    set outLine ""
	    set count 0
	}
    }
    if {$count != 0} {
	Display [string trimright $outLine]}
    return
}


#--------------------------------------------------------------------------
# Display help on help, the first occurance of a help page called "help" in
# the help root.

proc ::tclx::help::HelpOnHelp {} {
    set helpPage [lindex [ConvertPath /help] 0]
    if {[lempty $helpPage]} {
	error "No help page on help found" {} \
	    [list TCLXHELP NOHELPPAGE]
    }
    DisplayPage $helpPage
}


Filemanager

Name Type Size Permission Actions
arrayprocs.tcl File 1.6 KB 0644
autoload.tcl File 2.22 KB 0644
buildhelp.tcl File 15.61 KB 0644
compat.tcl File 9.8 KB 0644
convlib.tcl File 3.86 KB 0644
edprocs.tcl File 1.95 KB 0644
events.tcl File 1.03 KB 0644
fmath.tcl File 2.19 KB 0644
forfile.tcl File 1.4 KB 0644
globrecur.tcl File 3.11 KB 0644
help.tcl File 10.36 KB 0644
libtclx8.4.so File 155.52 KB 0755
pkgIndex.tcl File 77 B 0644
profrep.tcl File 5.1 KB 0644
pushd.tcl File 1.83 KB 0644
setfuncs.tcl File 2.92 KB 0644
showproc.tcl File 1.46 KB 0644
stringfile.tcl File 1.38 KB 0644
tcllib.tcl File 4.32 KB 0644
tclx.tcl File 2.05 KB 0644