You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

7878 lines
449 KiB

# -*- tcl -*-
# Maintenance Instruction: leave the 999999.xxx.x as is and use punkshell 'dev make' or bin/punkmake to update from <pkg>-buildversion.txt
# module template: punkshell/src/decktemplates/vendor/punk/modules/template_module-0.0.3.tm
#
# Please consider using a BSD or MIT style license for greatest compatibility with the Tcl ecosystem.
# Code using preferred Tcl licenses can be eligible for inclusion in Tcllib, Tklib and the punk package repository.
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# (C) 2025
#
# @@ Meta Begin
# Application punk::args::moduledoc::tclcore 999999.0a1.0
# Meta platform tcl
# Meta license MIT
# @@ Meta End
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# doctools header
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
#*** !doctools
#[manpage_begin punkshell_module_punk::args::moduledoc::tclcore 0 999999.0a1.0]
#[copyright "2025"]
#[titledesc {punk::args definitions for tcl core commands}] [comment {-- Name section and table of contents description --}]
#[moddesc {tcl core argument definitions}] [comment {-- Description at end of page heading --}]
#[require punk::args::moduledoc::tclcore]
#[keywords module]
#[description]
#[para] -
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
#*** !doctools
#[section Overview]
#[para] overview of punk::args::moduledoc::tclcore
#[subsection Concepts]
#[para] This is a punk::args module documentation package.
#[para] It provides punk::args definitions for core Tcl commands
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
## Requirements
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
#*** !doctools
#[subsection dependencies]
#[para] packages used by punk::args::moduledoc::tclcore
#[list_begin itemized]
package require Tcl 8.6-
package require punk::args
package require punk::ansi
package require textblock
#*** !doctools
#[item] [package {Tcl 8.6}]
#[item] [package {punk::args}]
#[item] [package {punk::ansi}]
#[item] [package {textblock}]
#*** !doctools
#[list_end]
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
#*** !doctools
#[section API]
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# Base namespace
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
tcl::namespace::eval punk::args::moduledoc::tclcore {
tcl::namespace::export {[a-z]*} ;# Convention: export all lowercase
#variable xyz
#for tcllib - we can potentially parse the doctools to get this info.
#for tcl core commands - the data is stored in man pages - which are not so easy to parse.
#todo - link to man pages
#TODO -
#if we want colour in arg definitions -we need to respect nocolor or change colour to off/ on
#If color included in a definition - it will need to be reloaded when colour toggled(?)
#if {[catch {package require punk::ansi}]} {
# set has_punkansi 0
# set A_WARN ""
# set A_RST ""
#} else {
# set has_punkansi 1
# set A_WARN [a+ red]
# set A_RST "\x1b\[0m"
#}
#we can't just strip ansi as there are non colour codes such as hyperlink that should be maintained whether color is on or off.
#for now we can use reverse - (like underline, is a non-colour attribute that remains effective when color off in punk::ansi)
set A_WARN \x1b\[7m
set A_RST \x1b\[0m
variable manbase_tcl
variable manbase_ext
set patch [info patchlevel]
lassign [split $patch .] major
if {$major < 9} {
set manbase_tcl "https://tcl.tk/man/tcl/TclCmd"
set manbase_ext .htm
} else {
set manbase_tcl "https://tcl.tk/man/tcl9.0/TclCmd"
set manbase_ext .html
}
proc manpage_tcl {cmd} {
variable manbase_tcl
variable manbase_ext
return ${manbase_tcl}/${cmd}${manbase_ext}
}
variable PUNKARGS
namespace eval argdoc {
tcl::namespace::import ::punk::ansi::a+
tcl::namespace::import ::punk::args::moduledoc::tclcore::manpage_tcl
# -- --- --- --- ---
#non colour SGR codes
# we can use these directly via ${$I} etc without marking a definition with @dynamic
#This is because they don't need to change when colour switched on and off.
set I [a+ italic]
set NI [a+ noitalic]
set B [a+ bold]
set N [a+ normal]
# -- --- --- --- ---
proc example {str} {
set str [string trimleft $str \n]
set block [punk::ansi::ansiwrap Web-gray [textblock::frame -ansibase [a+ Web-gray bold white] -ansiborder [a+ black White] -boxlimits {hl} -type block $str]]
set result [textblock::bookend_lines $block [a] "[a defaultbg] [a]"]
#puts $result
return $result
}
}
namespace eval argdoc {
#*** !doctools
#[subsection {Namespace punk::args::moduledoc::tclcore::argdoc}]
#[para] This is the main documentation namespace where calls to punk::args::define are made, and definitions are added to the punk::args::moduledoc::tclcore::argdoc::PUNKARGS variable.
#[para] Some utility functions exist here for use in the definitions.
#[list_begin definitions]
variable PUNKARGS
#*** !doctools
#[list_end] [comment {--- end definitions namespace punk::args::moduledoc::tclcore::argdoc ---}]
}
# -- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- ---
#
# library commands loaded via auto_index
#
# -- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
namespace eval argdoc {
lappend PUNKARGS [list {
@id -id ::parray
@cmd -name "Autoloading Built-in: parray" -help\
"Prints on standard output the names and values of all the elements in the
array arrayName, or just the names that match pattern (using the matching
rules of string_match) and their values if pattern is given.
ArrayName must be an array accessible to the caller of parray. It may either
be local or global. The result of this command is the empty string.
(loaded via auto_index)"
@values -min 1 -max 2
arrayName -type string -help\
"variable name of an array"
pattern -type string -optional 1 -help\
"Match pattern possibly containing glob characters"
} "@doc -name Manpage: -url [manpage_tcl library]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::foreachLine
@cmd -name "Autoloading Built-in: foreachLine" -help\
"This reads in the text file named ${$I}filename${$NI} one line at a time (using system
defaults for reading text files). It writes that line to the variable named
by ${$I}varName${$NI} and then executes ${$I}body${$NI} for that line. The result value of ${$I}body${$NI} is
ignored, but error, return, break and continue may be used within it to
produce an error, return from the calling context, stop the loop, or go to
the next line respectively. The overall result of ${$B}foreachLine${$N} is the empty
string (assuming no errors from I/O or from evaluating the body of the loop);
the file will be closed prior to the procedure returning."
@values -min 3 -max 3
varName
fileName
body
} "@doc -name Manpage: -url [manpage_tcl library]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::readFile
@cmd -name "Autoloading Built-in: readFile" -help\
"Reads in the file named in ${$I}filename${$NI} and returns its contents. The second
argument says how to read in the file, either as ${$B}text${$N} (using the system
defaults for reading text files) or as ${$B}binary${$N} (as uninterpreted bytes).
The default is ${$B}text${$N}. When read as text, this will include any trailing
newline. The file will be closed prior to the procedure returning."
@values -min 1 -max 2
fileName
#todo punk::args::synopsis - show prefix highlighting
mode -type literalprefix(text)|literalprefix(binary) -optional 1
#test
#mode -type {{literalprefix text | literalprefix binary}}
} "@doc -name Manpage: -url [manpage_tcl library]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::writeFile
@cmd -name "Autoloading Built-in: writeFile" -help\
"Writes the contents to the file named in ${$I}filename${$NI}. The optional second
argument says how to write to the file, either as ${$B}text${$N} (using the system
defaults for writing text files) or as ${$B}binary${$N} (as uninterpreted bytes).
The default is ${$B}text${$N}. If a trailing newline is required, it will need to
be provided in ${$I}contents${$NI}. The result of this command is the empty string;
the file will be closed prior to the procedure returning."
@values -min 2 -max 3
fileName
mode -type literalprefix(text)|literalprefix(binary) -optional 1
contents
} "@doc -name Manpage: -url [manpage_tcl library]" ]
lappend PUNKARGS [list {
@id -id ::tcl_endOfWord
@cmd -name "Autoloading Built-in: tcl_endOfWord"\
-summary\
"end-of-word index after supplied index ${$I}start${$NI}"\
-help\
"Returns the index of the first end-of-word location that occurs after a starting index start
in the string ${$I}str${$NI}. An end-of-word location is defined to be the first non-word
character following the first word character after the starting point. Returns -1 if there are
no more end-of-word locations after the starting point. See the description of tcl_wordchars and
tcl_nonwordchars below for more details on how Tcl determines which characters are word characters."
#'below' here means in the man page
#todo - supplementary (shared)::tcl_wordchars (shared)::tcl_nonwordchars documentation ?
@values -min 2 -max 2
str -type string
start -type indexexpression
} "@doc -name Manpage: -url [manpage_tcl library]" ]
lappend PUNKARGS [list {
@id -id ::tcl_startOfNextWord
@cmd -name "Autoloading Built-in: tcl_startOfNextWord"\
-summary\
"first start-of-word index after supplied index ${$I}start${$NI}"\
-help\
"Returns the index of the first start-of-word location that occurs after a starting index start
in the string str. A start-of-word location is defined to be the first word character following a
non-word character. Returns -1 if there are no more start-of-word locations after the starting point.
For example, to print the indices of the starts of each word in a string according to platform rules:
set theString "The quick brown fox"
for {set idx 0} {$idx >= 0} {
set idx [tcl_startOfNextWord $theString $idx]} {
puts "Word start index: $idx"
}
"
@values -min 2 -max 2
str -type string
start -type indexexpression
} "@doc -name Manpage: -url [manpage_tcl library]" ]
lappend PUNKARGS [list {
@id -id ::tcl_startOfPreviousWord
@cmd -name "Autoloading Built-in: tcl_startOfPreviousWord"\
-summary\
"first start-of-word index before supplied index ${$I}start${$NI}"\
-help\
"Returns the index of the first start-of-word location that occurs before a starting index start
in the string str. Returns -1 if there are no more start-of-word locations before the starting point."
@values -min 2 -max 2
str -type string
start -type indexexpression
} "@doc -name Manpage: -url [manpage_tcl library]" ]
lappend PUNKARGS [list {
@id -id ::tcl_wordBreakAfter
@cmd -name "Autoloading Built-in: tcl_wordBreakAfter"\
-summary\
"first word boundary index after supplied index ${$I}start${$NI}"\
-help\
"Returns the index of the first word boundary after the starting index start in the string str.
Returns -1 if there are no more boundaries after the starting point in the given string. The index
returned refers to the second character of the pair that comprises a boundary."
@values -min 2 -max 2
str -type string
start -type indexexpression
} "@doc -name Manpage: -url [manpage_tcl library]" ]
lappend PUNKARGS [list {
@id -id ::tcl_wordBreakBefore
@cmd -name "Autoloading Built-in: tcl_wordBreakBefore"\
-summary\
"first word boundary index before supplied index ${$I}start${$NI}"\
-help\
"Returns the index of the first word boundary before the starting index start in the string str.
Returns -1 if there are no more boundaries before the starting point in the given string. The index
returned refers to the second character of the pair that comprises a boundary."
@values -min 2 -max 2
str -type string
start -type indexexpression
} "@doc -name Manpage: -url [manpage_tcl library]" ]
lappend PUNKARGS [list {
@id -id ::tcl_findLibrary
@cmd -name "Autoloading Built-in: tcl_findLibrary"\
-summary\
"Extension initialization search function."\
-help\
"This is a standard search procedure for use by extensions during their initialization.
They call this procedure to look for their script library in several standard directories.
The last component of the name of the library directory is normally basenameversion
(e.g., tk8.0), but it might be library when in the build hierarchies. The initScript file
will be sourced into the interpreter once it is found. The directory in which this file is
found is stored into the global variable varName. If this variable is already defined
(e.g., by C code during application initialization) then no searching is done. Otherwise
the search looks in these directories: the directory named by the environment variable
enVarName; relative to the Tcl library directory; relative to the executable file in the
standard installation bin or bin/arch directory; relative to the executable file in the
current build tree; relative to the executable file in a parallel build tree."
@values -min 6 -max 6
basename -type string
version -type packageversion
patch -type any -help "UNUSED"
initScript -type string
enVarName -type string
varName -type string
} "@doc -name Manpage: -url [manpage_tcl library]" ]
lappend PUNKARGS [list {
@id -id ::tclPkgSetup
@cmd -name "Autoloading Built-in: tclPkgSetup"\
-summary\
"DEPRECATED package utility"\
-help\
"${$B}DEPRECATED${$N} support/utility procedure used by pkgIndex.tcl files that
enables -lazy in package index script.
It is invoked as part of a ${$B}package ifneeded${$N} script.
It calls ${$B}package provide${$N} to indicate that a package is available, then sets entries
in the auto_index array so that the package's files will be auto-loaded when the
commands are used.
Kept for backwards compatibility - may be removed at some point.
"
@values -min 2 -max 2
dir -type string -help "Directory containing all the files for this package."
pkg -type string -help "Name of the package (no version number)"
version -type packageversion
files -type list -help\
"List of files that constitute the package. Each element is a sub-list with three elements.
The first is the name of a file relative to $dir, the second is ${$B}load${$N} or ${$B}source${$N},
indicating whether the file is a loadable binary or a script to source, and the third is a
list of commands defined by this file."
} "@doc -name Manpage: -url [manpage_tcl library]" ]
}
# -- --- --- --- --- --- --- --- --- --- --- --- --- ---
# (end of auto_index commands)
# -- --- --- --- --- --- --- --- --- --- --- --- --- ---
#other tcl_library commands
lappend PUNKARGS [list {
@id -id ::auto_execok
@cmd -name "tcl_library Built-in: auto_execok"\
-summary\
"Retrieve executable file or shell builtin for use with exec."\
-help\
"Determines whether there is an executable file or shell builtin by the name ${$I}cmd${$NI}. If so, it
returns a list of arguments to be passed to ${$B}exec${$N} to execute the executable file or shell
builtin named by ${$I}cmd${$NI}. If not, it returns an empty string. This command examines the
directories in the current search path (given by the PATH environment variable) in its
search for an executable file named ${$I}cmd${$NI}. On Windows platforms, the search is expanded with
the same directories and file extensions as used by ${$B}exec${$N}. ${$B}Auto_execok${$N} remembers information
about previous searches in an array named auto_execs; this avoids the path search in future
calls for the same ${$I}cmd${$NI}. The command ${$B}auto_reset${$N} may be used to force ${$B}auto_execok${$N} to forget
its cached information.
For example, to run the umask shell builtin on Linux, you would do:
exec {*}[auto_execok umask]
To run the DIR shell builtin on Windows, you would do:
exec {*}[auto_execok dir]
To discover if there is a frobnicate binary on the user's PATH, you would do:
set mayFrob [expr {[llength [auto_execok frobnicate]] > 0}]
"
@values -min 2 -max 2
cmd -type string
} "@doc -name Manpage: -url [manpage_tcl library]" ]
namespace eval argdoc {
punk::args::define {
@id -id ::tcl::info::args
@cmd -name "Built-in: tcl::info::args"\
-summary\
"procedure parameters"\
-help\
"Returns the names of the parameters to the procedure named ${$I}procname${$NI}."
@values -min 1 -max 1
procname -type string -optional 0
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl info]"
punk::args::define {
@id -id ::tcl::info::body
@cmd -name "Built-in: tcl::info::body"\
-summary\
"procedure body"\
-help\
"Returns the body procedure named ${$I}procname${$NI}."
@values -min 1 -max 1
procname -type string -optional 0
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl info]"
punk::args::define {
@id -id ::tcl::info::cmdcount
@cmd -name "Built-in: tcl::info::cmdcount"\
-summary\
"Interp's total commands evaluated"\
-help\
"Returns the total number of commands evaluated in this interpreter."
@leaders -min 0 -max 0
@values -min 0 -max 0
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl info]"
punk::args::define {
@id -id ::tcl::info::cmdtype
@cmd -name "Built-in: tcl::info::cmdtype"\
-summary\
"command type: proc, ensemble etc"\
-help\
"Returns the type of the command named ${$I}commandName${$NI}.
Built-in types are:
${$B}alias${$N}
${$I}commandName${$NI} was created by 'interp alias'. In a safe interpreter an
alias is only visible if both the alias and the target are visible.
${$B}coroutine${$N}
${$I}commandName${$NI} was created by 'coroutine'.
${$B}ensemble${$N}
${$I}commandName${$NI} was created by 'namespace ensemble'.
${$B}import${$N}
${$I}commandName${$NI} was created by 'namespace import'.
${$B}native${$N}
${$I}commandName${$NI} was created by the 'Tcl_CreateObjCommand' interface
directly without further registration of the type of command.
${$B}object${$N}
${$I}commandName${$NI} is the public comand that represents an instance
of oo::object or one of its subclasses.
${$B}privateObject${$N}
${$I}commandName${$NI} is the private command, my by default,
that represents an instance of oo::object or one of its subclasses.
${$B}proc${$N}
${$I}commandName${$NI} was created by 'proc'.
${$B}interp${$N}
${$I}commandName${$NI} was created by 'interp create'.
${$B}zlibStream${$N}
${$I}commandName${$NI} was created by 'zlib stream'.
"
@values -min 1 -max 1
commandName -type string
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl info]"
punk::args::define {
@id -id ::tcl::info::coroutine
@cmd -name "Built-in: tcl::info::coroutine"\
-summary\
"current coroutine"\
-help\
"Returns the name of the current ${$B}coroutine${$N}, or the empty string if there
is no current coroutine or the current coroutine has been deleted."
@leaders -min 0 -max 0
@values -min 0 -max 0
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl info]"
punk::args::define {
@id -id ::tcl::info::default
@cmd -name "Built-in: tcl::info::default"\
-summary\
"default parameter value"\
-help\
"If the parameter ${$I}parameter${$NI} for the procedure named ${$I}procname${$NI}
has a default value, stores that value in ${$I}varname${$NI} and returns ${$B}1${$N}.
Otherwise, returns ${$B}0${$N}."
@values -min 3 -max 3
procname -type string -optional 0
parameter
varname
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl info]"
punk::args::define {
@id -id ::tcl::info::functions
@cmd -name "Built-in: tcl::info::functions"\
-summary\
"defined math functions"\
-help\
"If ${$I}pattern${$NI} is not given, returns a list of all the math functions currently defined.
If ${$I}pattern${$NI} is given, returns only those names that match ${$I}pattern${$NI} according to ${$B}string match${$N}."
@values -min 0 -max 2
pattern -type string -optional 1
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl info]"
punk::args::define {
@id -id ::tcl::info::globals
@cmd -name "Built-in: tcl::info::globals"\
-summary\
"defined global variables"\
-help\
"If ${$I}pattern${$NI} is not given, returns a list of all the names of currently-defined
global variables. Global variables are variables in the global namespace. If ${$I}pattern${$NI} is
given, only those names matching ${$I}pattern${$NI} are returned. Matching is determined using the
same rules as for ${$B}string match${$N}."
@values -min 0 -max 2
pattern -type string -optional 1
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl info]"
punk::args::define {
@id -id ::tcl::info::hostname
@cmd -name "Built-in: tcl::info::hostname"\
-summary\
"Current host name"\
-help\
"Returns the name of the current host.
This name is not guaranteed to be the fully-qualified domain name of the host.
Where machines have several different names, as is common on systems with
both TCP/IP (DNS) and NetBIOS-based networking installed, it is the name that
is suitable for TCP/IP networking that is returned."
@leaders -min 0 -max 0
@values -min 0 -max 0
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl info]"
punk::args::define {
@id -id ::tcl::info::level
@cmd -name "Built-in: tcl::info::level"\
-summary\
"Calling level or command at level"\
-help\
"If number is not given, the level this routine was called from. Otherwise
returns the complete command active at the given level. If number is greater
than ${$B}0${$N}, it is the desired level. Otherwise, it is number levels up from the
current level. A complete command is the words in the command, with all
substitutions performed, meaning that it is a list. See ${$B}uplevel${$N} for more
information on levels."
@values -min 0 -max 2
level -type integer -optional 1
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl info]"
punk::args::define {
@id -id ::tcl::info::library
@cmd -name "Built-in: tcl::info::library"\
-summary\
"library directory"\
-help\
"Returns the value of ${$B}tcl_library${$N}, which is the name of the library
directory in which the scripts distributed with Tcl scripts are stored."
@leaders -min 0 -max 0
@values -min 0 -max 0
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl info]"
punk::args::define {
@id -id ::tcl::info::loaded
@cmd -name "Built-in: tcl::info::loaded"\
-summary\
"loaded binary library files"\
-help\
"Returns the name of each file loaded in interp by the load command with
prefix prefix . If prefix is not given, returns a list where each item is
the name of the loaded file and the prefix for which the file was loaded.
For a statically-loaded package the name of the file is the empty string.
For interp, the empty string is the current interpreter."
@values -min 0 -max 2
interp -type string -optional 1
prefix -type string -optional 1
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl info]"
punk::args::define {
@id -id ::tcl::info::locals
@cmd -name "Built-in: tcl::info::locals"\
-summary\
"local variables (proc/apply)"\
-help\
"If ${$I}pattern${$NI} is given, returns the name of each local variable matching
pattern according to ${$B}string match${$N}. Otherwise, returns the name of each local
variable. A variables defined with the ${$B}global${$N}, ${$B}upvar${$N} or ${$B}variable${$N} is not local."
@values -min 0 -max 2
pattern -type string -optional 1
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl info]"
punk::args::define {
@id -id ::tcl::info::nameofexecutable
@cmd -name "Built-in: tcl::info::nameofexecutable"\
-summary\
"Executable absolute path"\
-help\
"Returns the absolute pathname of the program for the current interpreter.
If such a file can not be identified an empty string is returned."
@leaders -min 0 -max 0
@values -min 0 -max 0
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl info]"
punk::args::define {
@id -id ::oo::InfoObject::call
@cmd -name "Built-in: oo::InfoObject::call" -help\
"Returns a description of the method implementations that are used to provide
${$I}object's${$NI} implementation of ${$I}method${$NI}. This consists of a
list of lists of four elements, where each sublist consists of:
element 0: a word that describes the general type of method implementation, being
one of
${$B}method${$N} for an ordinary method, ${$B}filter${$N} for an applied filter,
${$B}private${$N} for a private method, and ${$B}unknown${$N} for a method that
is invoked as part of unknown method handling.
element 1: a word giving the name of the particular method invoked (which is always
the same as method for the ${$B}method${$N} type, and \"${$B}unknown${$N}\"
for the ${$B}unknown${$N} type)
element 2: a word giving what defined the method (the fully qualified name of the
class, or the literal string ${$B}object${$N} if the method implementation is on
an instance)
element 3: a word describing the type of method implementation
(see ${$B}info object methodtype${$N})
Note that there is no inspection of whether the method implementations actually use
${$B}next${$N} to transfer control along the call chain, and the call chains that
this command files do not actually contain private methods."
@values -min 2 -max 2
object
method
} "@doc -name Manpage: -url [manpage_tcl info]"
#---------
punk::args::define {
@id -id ::oo::InfoClass::call
@cmd -name "Built-in: oo::InfoClass::call" -help\
"Returns a description of the method implementations that are used to provide
a stereotypical instance of ${$I}class's${$NI} implementation of ${$I}method${$NI}.
(stereotypical instances being objects instantiated by a class without having any
object-specific definitions added).
This consists of a
list of lists of four elements, where each sublist consists of:
element 0: a word that describes the general type of method implementation, being
one of
${$B}method${$N} for an ordinary method, ${$B}filter${$N} for an applied filter,
${$B}filter${$N} for an applied filter,
${$B}private${$N} for a private method, and ${$B}unknown${$N} for a method that
is invoked as part of unknown method handling.
element 1: a word giving the name of the particular method invoked (which is always
the same as method for the ${$B}method${$N} type, and \"${$B}unknown${$N}\"
for the ${$B}unknown${$N} type)
element 2: a word giving the fully qualified name of the class that defined the
method
element 3: a word describing the type of method implementation
(see ${$B}info class methodtype${$N})
Note that there is no inspection of whether the method implementations actually use
${$B}next${$N} to transfer control along the call chain, and the call chains that
this command files do not actually contain private methods."
@values -min 2 -max 2
class
method
} "@doc -name Manpage: -url [manpage_tcl info]"
proc info_subcommands {} {
#package require punk::ns
#set subdict [punk::ns::ensemble_subcommands -return dict info]
#set allsubs [dict keys $subdict]
dict set groups "system" {hostname library nameofexecutable patchlevel script sharedlibextension tclversion}
dict set groups "proc introspection" {args body default}
dict set groups "variables" {constant consts exists globals locals vars}
dict set groups "oo object introspection" {class object}
return [punk::args::ensemble_subcommands_definition -groupdict $groups -columns 2 info]
}
set DYN_INFO_SUBCOMMANDS {${[punk::args::moduledoc::tclcore::argdoc::info_subcommands]}}
lappend PUNKARGS [list {
@dynamic
@id -id ::info
@cmd -name "Built-in: info"\
-summary\
"Information about the state of the Tcl interpreter"\
-help\
"Information about the state of the Tcl interpreter"
#a root docid for an ensemble-like command must always specify a -max for @leaders
@leaders -min 1 -max 1
${$DYN_INFO_SUBCOMMANDS}
@values -unnamed true
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl info]" ]
}
#An idiom for sharing common features - incomplete - todo work out what happens with (default)::id that has leaders,opts,values
#todo @cmd -help+ text (append to existing help that came from a default?)
lappend PUNKARGS [list {
@id -id "(default)::tcl::binary::*::base64"
@cmd -help\
"The base64 binary encoding is commonly used in mail messages and XML documents,
and uses mostly upper and lower case letters and digits. It has the distinction
of being able to be rewrapped arbitrarily without losing information.
"
} "@doc -name Manpage: -url [manpage_tcl binary]" ]
lappend PUNKARGS [list {
@id -id "::tcl::binary::encode::base64"
@default -id (default)::tcl::binary::*::base64
@cmd -name "binary encode base64"
-maxlen -type integer -help\
"Indicates that the output should be split into lines of no more than length
characters. By default, lines are not split."
-wrapchar -type character -default \n -help\
"Indicates that, when lines are split because of the -maxlen option, character
should be used to separate lines. By default, this is a newline character, \"\\n\"."
@values -min 1 -max 1
data -type string
} ]
lappend PUNKARGS [list {
@id -id "::tcl::binary::decode::base64"
@default -id (default)::tcl::binary::*::base64
@cmd -name "binary decode base64"
-strict -type none -help\
"Instructs the decoder to throw an error if it encounters any characters that
are not strictly part of the encoding itself. Otherwise it ignores them.
RFC 2045 calls for base64 decoders to be non-strict."
@values -min 1 -max 1
data -type string
} ]
lappend PUNKARGS [list {
@id -id "(default)::tcl::binary::*::hex"
@cmd -help\
"The hex binary encoding converts each byte to a pair of hexadecimal digits
that represent the byte value as a hexadecimal integer. When encoding, lower
characters are used. When decoding, upper and lower characters are accepted."
} "@doc -name Manpage: -url [manpage_tcl binary]" ]
lappend PUNKARGS [list {
@id -id "::tcl::binary::encode::hex"
@default -id (default)::tcl::binary::*::hex
@cmd -name "binary encode hex"\
-summary "Encode each byte to a pair of hex digits (lower case output)"
@values -min 1 -max 1
data -type string
} ]
lappend PUNKARGS [list {
@id -id "::tcl::binary::decode::hex"
@default -id (default)::tcl::binary::*::hex
@cmd -name "binary encode hex"\
-summary "Decode contiguous pairs of hex digits to bytes (input may be upper or lower case)"
-strict -type none -help\
"Instructs the decoder to throw an error if it encounters whitespace
characters. Otherwise it ignores them.
Whether -strict is applied or not, a trailing unpaired hex digit is ignored."
@values -min 1 -max 1
data -type string
}]
lappend PUNKARGS [list {
@id -id "(default)::tcl::binary::*::uuencode"
@cmd -help\
"The uuencode binary encoding used to be common for transfer of data between Unix
systems and on USENT, but is less common these days, having been largely
superseded by the base64 binary encoding.
Note that neither the encoder nor the decoder handle the header and footer of the
uuencode format."
} "@doc -name Manpage: -url [manpage_tcl binary]" ]
lappend PUNKARGS [list {
@id -id "::tcl::binary::encode::uuencode"
@default -id (default)::tcl::binary::*::uuencode
#todo @cmd -help+ "Changing the options may produce files that other implementations of decoders cannot process"
@cmd -name "binary encode uuencode"
-maxlen -type integer -default 61 -range {5 85} -help\
"Indicates the maximum number of characters to produce for each encoded line.
The valid range is 5 to 85. Line lengths outside that range cannot be
accommodated by the encoding format."
-wrapchar -type string -default \n -help\
"Indicates the character(s) to use to mark the end of each encoded line.
Acceptable values are a sequence of zero or more character from the set
{ \\x09 (TAB), \\x0B (VT), \\x0C (FF), \\x0D (CR) } followed by zero or
one newline \\x0A (LF). Any other values are rejected because they would
generate encoded text that could not be decoded. The default value is a
single newline.
"
@values -min 1 -max 1
data -type string
} ]
lappend PUNKARGS [list {
@id -id "::tcl::binary::decode::uuencode"
@default -id (default)::tcl::binary::*::uuencode
@cmd -name "binary decode uuencode"
-strict -type none -help\
"Instructs the decoder to throw an error if it encounters anything outside
of the standard encoding format. Without this option, the decoder tolerates
some deviations, mostly to forgive reflows of lines between the encoder and
decoder."
@values -min 1 -max 1
data -type string
} ]
#JJJ
namespace eval argdoc {
if {[catch {encoding profiles} ENCODING_PROFILES]} {
#tcl <= 8.6x? - no profiles
lappend PUNKARGS [list {
@id -id "::tcl::encoding::convertfrom"
@cmd -name "encoding convertfrom"\
-summary\
"encoded binary string data to string"\
-help\
"Converts data, which should be in the form of a binary string encoded as per encoding,
to a Tcl string. If encoding is not specified, the current system encoding is used."
@form -form basic
@values -min 1 -max 2
encoding -type string -typesynopsis ${$I}encoding${$NI} -optional 1
data -type string -help "binary string"
} "@doc -name Manpage: -url [manpage_tcl encoding]" ]
lappend PUNKARGS [list {
@id -id "::tcl::encoding::convertto"
@cmd -name "encoding convertto"\
-summary\
"encoded binary string from string data"\
-help\
"Convert string to the specified encoding. The result is a Tcl binary string that
contains the sequence of bytes representing the converted string in the specified
encoding. If encoding is not specified, the current system encoding is used."
@form -form basic
@values -min 1 -max 2
encoding -type string -typesynopsis ${$I}encoding${$NI} -optional 1
data -type string
} "@doc -name Manpage: -url [manpage_tcl encoding]" ]
} else {
#tcl 9-
lappend PUNKARGS [list {
@id -id "::tcl::encoding::convertfrom"
@cmd -name "encoding convertfrom"\
-summary\
"encoded binary string data to string"\
-help\
"Converts data, which should be in the form of a binary string encoded as per encoding,
to a Tcl string. If encoding is not specified, the current system encoding is used."
@form -form basic
@values -min 1 -max 2
encoding -type string -typesynopsis ${$I}encoding${$NI} -optional 1
data -type string -help "binary string"
#todo - load choices from result of [encoding profiles]
@form -form full
@leaders -min 0 -max 0
@opts
-profile -type string -typesynopsis ${$I}profile${$NI} -help\
"Determines the command behavior in the presence of conversion errors.
Any premature termination of processing due to errors is reported through an exception
if the -failindex option is not specified.
Operations involving encoding transforms may encounter several types of errors such as
invalid sequences in the source data, characters that cannot be encoded in the target
encoding and so on. A profile prescribes the strategy for dealing with such errors in
one of two ways:
Terminating further processing of the source data. The profile does not determine how
this premature termination is conveyed to the caller. By default, this is signalled
by raising an exception. If the -failindex option is specified, errors are reported
through that mechanism.
Continue further processing of the source data using a fallback strategy such as
replacing or discarding the offending bytes in a profile-defined manner.
The following profiles are currently implemented with strict being the default if the -profile is not specified."\
-choicecolumns 1\
-choices {${$ENCODING_PROFILES}}\
-choiceprefix 0\
-choicelabels {
strict
" The strict profile always stops processing when an conversion error is encountered.
The error is signalled via an exception or the -failindex option mechanism.
The strict profile implements a Unicode standard conformant behavior."
tcl8
" The tcl8 profile always follows the first strategy above and corresponds to the behavior
of encoding transforms in Tcl 8.6. When converting from an external encoding other than
utf-8 to Tcl strings with the encoding convertfrom command, invalid bytes are mapped to
their numerically equivalent code points. For example, the byte 0x80 which is invalid in
ASCII would be mapped to code point U+0080. When converting from utf-8, invalid bytes
that are defined in CP1252 are mapped to their Unicode equivalents while those that are
not fall back to the numerical equivalents. For example, byte 0x80 is defined by CP1252
and is therefore mapped to its Unicode equivalent U+20AC while byte 0x81 which is not
defined by CP1252 is mapped to U+0081. As an additional special case, the sequence
0xC0 0x80 is mapped to U+0000. When converting from Tcl strings to an external encoding
format using encoding convertto, characters that cannot be represented in the target
encoding are replaced by an encoding-dependent character, usually the question mark ?."
replace
" Like the tcl8 profile, the replace profile always continues processing on conversion
errors but follows a Unicode standard conformant method for substitution of invalid
source data. When converting an encoded byte sequence to a Tcl string using encoding
convertfrom, invalid bytes are replaced by the U+FFFD REPLACEMENT CHARACTER code point.
When encoding a Tcl string with encoding convertto, code points that cannot be represented
in the target encoding are transformed to an encoding-specific fallback character, U+FFFD
REPLACEMENT CHARACTER for UTF targets and generally `?` for other encodings."
}
-failindex -type string -typesynopsis ${$I}var${$NI} -help\
"If specified, instead of an exception being raised on premature termination,
the result of the conversion up to the point of the error is returned as the
result of the command. In addition, the index of the source byte triggering
the error is stored in var. If no errors are encountered, the entire result
of the conversion is returned and the value -1 is stored in var."
@values -min 2 -max 2
encoding -type string -optional 0
data -type string -help "binary string"
} "@doc -name Manpage: -url [manpage_tcl encoding]" ]
lappend PUNKARGS [list {
@id -id "::tcl::encoding::convertto"
@cmd -name "encoding convertto"\
-summary\
"encoded binary string from string data"\
-help\
"Convert string to the specified encoding. The result is a Tcl binary string that
contains the sequence of bytes representing the converted string in the specified
encoding. If encoding is not specified, the current system encoding is used."
@form -form basic
@values -min 1 -max 2
encoding -type string -typesynopsis ${$I}encoding${$NI} -optional 1
data -type string
@form -form full
@leaders -min 0 -max 0
@opts
${[punk::args::resolved_def -form 1 -types opts ::tcl::encoding::convertfrom -*]}
@values -min 2 -max 2
encoding -type string -optional 0
data -type string
} "@doc -name Manpage: -url [manpage_tcl encoding]" ]
}
}
namespace eval argdoc {
lappend PUNKARGS [list {
@id -id "::tcl::encoding::dirs"
@cmd -name "encoding dirs"\
-summary\
"get/set encoding data-file search directories"\
-help\
"Tcl can load encoding data files from the file system that describe
additional encodings for it to work with. This command sets the search
path for ${$B}*.enc${$N} encoding data files to the list of directories
${$I}directoryList${$NI}. If ${$I}directoryList${$NI} is omitted then the
command returns the current list of directories that make up the search
path. It is an error for ${$I}directoryList${$NI} to not be a valid list.
If, when a search for an encoding data file is happening, an element in
${$I}directoryList${$NI} does not refer to a readable, searchable
directory, that element is ignored."
@values -min 0 -max 1
directoryList -optional 1 -type list
} "@doc -name Manpage: -url [manpage_tcl encoding]" ]
lappend PUNKARGS [list {
@id -id "::tcl::encoding::names"
@cmd -name "encoding names"\
-summary\
"list available encodings"\
-help\
"Returns a list containing the names of all of the encodings that are
currently available. The encodings utf-8 and iso8859-1 are
guaranteed to be present in the list."
@values -min 0 -max 0
} "@doc -name Manpage: -url [manpage_tcl encoding]" ]
lappend PUNKARGS [list {
@id -id "::tcl::encoding::profiles"
@cmd -name "encoding profiles"\
-summary\
"list encoding profile names"\
-help\
"Returns a list of the names of encoding profiles. See PROFILES below."
@values -min 0 -max 0
} "@doc -name Manpage: -url [manpage_tcl encoding]" ]
lappend PUNKARGS [list {
@id -id "::tcl::encoding::system"
@cmd -name "encoding system"\
-summary\
"set or query system encoding."\
-help\
"Set the system encoding to ${$I}encoding${$NI}. If ${$I}encoding${$NI} is
omitted then the command returns the current system encoding.
The system encoding is used whenever Tcl passes strings to system calls."
@values -min 0 -max 1
encoding -type string -optional 1
} "@doc -name Manpage: -url [manpage_tcl encoding]" ]
lappend PUNKARGS [list {
@id -id "::tcl::encoding::user"
@cmd -name "encoding user"\
-summary\
"get user encoding"\
-help\
"Returns the name of encoding as per the user's preferences.
On Windows systems, this is based on the user's code page settings in
the registry. On other platforms, the returned value is the same as
returned by encoding system."
@values -min 0 -max 0
} "@doc -name Manpage: -url [manpage_tcl encoding]" ]
proc encoding_subcommands {} {
#package require punk::ns
#set subdict [punk::ns::ensemble_subcommands -return dict info]
#set allsubs [dict keys $subdict]
dict set groups "" {convertfrom convertto dirs names profiles system user}
return [punk::args::ensemble_subcommands_definition -groupdict $groups -columns 1 encoding]
}
set ENCODING_SUBCOMMANDS {${[punk::args::moduledoc::tclcore::argdoc::encoding_subcommands]}}
#by making the doc for the ensemble @dynamic - any additional subcommands added to the ensemble at runtime will show as subcommands in the documentation for ::encoding
punk::args::define {
@dynamic
@id -id ::encoding
@cmd -name "Built-in: encoding"\
-summary\
"Manipulate encodings."\
-help\
"Strings in Tcl are logically a sequence of Unicode characters. These strings are represented
in memory as a sequence of bytes that may be in one of several encodings: modified UTF-8
(which uses 1 to 4 bytes per character), or a custom encoding start as 8 bit binary data.
Different operating system interfaces or applications may generate strings in other encodings
such as Shift-JIS. The encoding command helps to bridge the gap between Unicode and these
other formats."
@leaders -min 1 -max 1
${$ENCODING_SUBCOMMANDS}
@values -unnamed true
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl encoding]"\
{@examples -help {
These examples use the utility proc below that prints the Unicode code points comprising a Tcl string.
${[punk::args::moduledoc::tclcore::argdoc::example {
proc codepoints s {join [lmap c [split $s {}] {
string cat U+ [format %.6X [scan $c %c]]}]
}
}]}
Example 1: convert a byte sequence in Japanese euc-jp encoding to a TCL string:
${[punk::args::moduledoc::tclcore::argdoc::example {
% codepoints [encoding convertfrom euc-jp "\xA4\xCF"]
U+00306F
}]}
The result is the unicode codepoint \u306F, which is the Hiragana letter HA.
Example 2: Error handling based on profiles:
The letter A is Unicode character U+0041 and the byte "\x80" is invalid in ASCII encoding.
${[punk::args::moduledoc::tclcore::argdoc::example {
% codepoints [encoding convertfrom -profile tcl8 ascii A\x80]
U+000041 U+000080
% codepoints [encoding convertfrom -profile replace ascii A\x80]
U+000041 U+00FFFD
% codepoints [encoding convertfrom -profile strict ascii A\x80]
unexpected byte sequence starting at index 1: '\x80'
}]}
Example 3: Get partial data and the error location:
${[punk::args::moduledoc::tclcore::argdoc::example {
% codepoints [encoding convertfrom -profile strict -failindex idx ascii AB\x80]
U+000041 U+000042
% set idx
2
}]}
Example 4: Encode a character that is not representable in ISO8859-1:
${[punk::args::moduledoc::tclcore::argdoc::example {
% encoding convertto iso8859-1 A\u0141
A?
% encoding convertto -profile strict iso8859-1 A\u0141
unexpected character at index 1: 'U+000141'
% encoding convertto -profile strict -failindex idx iso8859-1 A\u0141
A
% set idx
1
}]}
}
}
}
lappend PUNKARGS [list {
@id -id ::time
@cmd -name "Built-in: time" -help\
"Calls the Tcl interpreter count times to evaluate script
(or once if count is not specified). It will then return
a string of the form
503.2 microseconds per iteration
which indicates the average amount of time required per
iteration, in microseconds. Time is measured in elapsed
time, not CPU time.
(see also: timerate)"
@values -min 1 -max 2
script -type script
count -type integer -default 1 -optional 1
} "@doc -name Manpage: -url [manpage_tcl time]" ]
namespace eval argdoc {
lappend PUNKARGS [list {
@id -id ::tcl::chan::blocked
@cmd -name "Built-in: tcl::chan::blocked" -help\
"This tests whether the last input operation on the channel called ${$I}channel${$NI}
failed because it would otherwise have caused the process to block, and returns 1
if that was the case. It returns 0 otherwise. Note that this only ever returns 1
when the channel has been configured to be non-blocking; all Tcl channels have
blocking turned on by default"
@values -min 1 -max 1
channel -help \
""
} "@doc -name Manpage: -url [manpage_tcl chan]" ]
lappend PUNKARGS [list {
@id -id ::tcl::chan::close
@cmd -name "Built-in: tcl::chan::close" -help\
"Close and destroy the channel called channel. Note that this deletes all existing file-events
registered on the channel. If the direction argument (which must be read or write or any
unique abbreviation of them) is present, the channel will only be half-closed, so that it can
go from being read-write to write-only or read-only respectively. If a read-only channel is
closed for reading, it is the same as if the channel is fully closed, and respectively similar
for write-only channels. Without the direction argument, the channel is closed for both reading
and writing (but only if those directions are currently open). It is an error to close a
read-only channel for writing, or a write-only channel for reading.
As part of closing the channel, all buffered output is flushed to the channel's output device
(only if the channel is ceasing to be writable), any buffered input is discarded (only if the
channel is ceasing to be readable), the underlying operating system resource is closed and
channel becomes unavailable for future use (both only if the channel is being completely closed).
If the channel is blocking and the channel is ceasing to be writable, the command does not return
until all output is flushed. If the channel is non-blocking and there is unflushed output, the
channel remains open and the command returns immediately; output will be flushed in the
background and the channel will be closed when all the flushing is complete.
If channel is a blocking channel for a command pipeline then chan close waits for the child
processes to complete.
If the channel is shared between interpreters, then chan close makes channel unavailable in the
invoking interpreter but has no other effect until all of the sharing interpreters have closed the
channel. When the last interpreter in which the channel is registered invokes chan close (or close),
the cleanup actions described above occur. With half-closing, the half-close of the channel only
applies to the current interpreter's view of the channel until all channels have closed it in that
direction (or completely). See the interp command for a description of channel sharing.
Channels are automatically fully closed when an interpreter is destroyed and when the process exits.
Channels are switched to blocking mode, to ensure that all output is correctly flushed before the
process exits.
The command returns an empty string, and may generate an error if an error occurs while flushing
output. If a command in a command pipeline created with open returns an error, chan close generates
an error (similar to the exec command.)
Note that half-closes of sockets and command pipelines can have important side effects because they
result in a shutdown() or close() of the underlying system resource, which can change how other
processes or systems respond to the Tcl program.
Channels are automatically closed when an interpreter is destroyed and when the process exits.
From 8.6 on (TIP#398), nonblocking channels are no longer switched to blocking mode when exiting;
this guarantees a timely exit even when the peer or a communication channel is stalled. To ensure
proper flushing of stalled nonblocking channels on exit, one must now either (a) actively switch
them back to blocking or (b) use the environment variable TCL_FLUSH_NONBLOCKING_ON_EXIT, which when
set and not equal to 0 restores the previous behavior."
@values -min 1 -max 1
channel
direction -optional 1 -choices {read write}
} "@doc -name Manpage: -url [manpage_tcl chan]" ]
lappend PUNKARGS [list {
@id -id ::fconfigure
@cmd -name "Built-in: chan configure" -help\
"Query or set the configuration options of the channel named ${$I}channel${$NI}
If no ${$I}optionName${$NI} or ${$I}value${$NI} arguments are supplied, the
command returns a list containing alternating option names and values for the
channel. If ${$I}optionName${$NI} is supplied but no ${$I}value${$NI} then the
command returns the current value of the given option. If one or more pairs
of ${$I}optionName${$NI} and ${$I}value${$NI} are supplied, the command sets each
of the named options to the corresponding value; in this case the return
value is an empty string.
The options described below are supported for all channels. In addition, each
channel type may add options that only it supports. See the manual entry for
the command that creates each type of channel for the options supported by
that specific type of channel. For example, see the manual entry for the
${$B}socket${$N} command for additional options for sockets, and the ${$B}open${$N}
command for additional options for serial devices.
${$B}-blocking${$N} ${$I}boolean${$NI}
The ${$B}-blocking${$N} option determines whether I/O operations on the
channel can cause the process to block indefinitely. The value of the
option must be a proper boolean value. Channels are normally in blocking
mode; if a channel is placed into non-blocking mode it will affect the
operation of the ${$B}chan gets, chan read, chan puts, chan flush,${$N}
and ${$B}chan close${$N} commands; see the documentation for those
commands for details. For non-blocking mode to work correctly, the
application must be using the Tcl event loop (e.g. by calling
${$B}Tcl_DoOneEvent${$N} or invoking the ${$B}vwait${$N} command).
${$B}-buffering${$N} ${$I}newValue${$NI}
If ${$I}newValue${$NI} is ${$B}full${$N} then the I/O system will buffer output until its
internal buffer is full or until the ${$B}chan flush${$N} command is invoked. If
${$I}newValue${$NI} is ${$B}line${$N}, then the I/O system will automatically flush output for
the channel whenever a newline character is output. If ${$I}newValue${$NI} is ${$B}none${$N},
the I/O system will flush automatically after every output operation. The
default is for ${$B}-buffering${$N} to be set to ${$B}full${$N} except for channels that
connect to terminal-like devices; for these channels the initial setting
is ${$B}line${$N}. Additionally, ${$B}stdin${$N} and ${$B}stdout${$N} are initially set to ${$B}line${$N}, and
${$B}stderr${$N} is set to ${$B}none${$N}.
${$B}-buffersize${$N} ${$I}newSize${$NI}
${$I}newSize${$NI} must be an integer; its value is used to set the size of buffers,
in bytes, subsequently allocated for this channel to store input or output.
${$I}newSize${$NI} must be a number of no more than one million, allowing buffers of
up to one million bytes in size.
${$B}-encoding${$N} ${$I}name${$NI}
${$B}-eofchar${$N} ${$I}char${$NI}
${$B}-profile${$N} ${$I}profile${$NI}
${$B}-translation${$N} ${$I}translation${$NI}"
@form -form {getall}
@values -min 1 -max 1
channel
@form -form {getone}
@values -min 2 -max 2
channel
optionName
@form -form {set}
@values -min 3 -max -1
channel
"optionName value" -type {string any} -typesynopsis {${$I}optionName value${$NI}} -multiple 1 -optional 0
} "@doc -name Manpage: -url [manpage_tcl chan]" ]
lappend PUNKARGS [list {
@id -id ::tcl::chan::eof
@cmd -name "Built-in: tcl::chan::eof"\
-summary\
"Check for end of file condition on channel"\
-help\
"Test whether the last input operation on the channel called ${$I}channel${$NI}
failed because the end of the data stream was reached, returning 1 if end-of-file
was reached, and 0 otherwise."
@values -min 1 -max 1
channel -help \
""
} "@doc -name Manpage: -url [manpage_tcl chan]" ]
#event
lappend PUNKARGS [list {
@id -id ::tcl::chan::flush
@cmd -name "Built-in: tcl::chan::flush"\
-summary\
"Flush pending output."\
-help\
"Ensures that all pending output for the channel called channel is written.
If the channel is in blocking mode the command does not return until all the buffered output
has been flushed to the channel. If the channel is in non-blocking mode, the command may
return before all buffered output has been flushed; the remainder will be flushed in the
background as fast as the underlying file or device is able to absorb it."
@values -min 1 -max 1
channel
} "@doc -name Manpage: -url [manpage_tcl chan]" ]
lappend PUNKARGS [list {
@id -id ::tcl::chan::gets
@cmd -name "Built-in: tcl::chan::gets"\
-summary\
"Read a line from channel."\
-help\
"Reads a line from the channel consisting of all characters up to the next end-of-line sequence
or until end of file is seen. The line feed character corresponding to end-of-line sequence is
not included as part of the line. If the varName argument is specified, the line is stored in
the variable of that name and the command returns the length of the line. If varName is not
specified, the command returns the line itself as the result of the command.
If a complete line is not available and the channel is not at EOF, the command will block in the
case of a blocking channel. For non-blocking channels, the command will return the empty string
as the result in the case of varName not specified and -1 if it is.
If a blocking channel is already at EOF, the command returns an empty string if varName is not
specified. Note an empty string result can also be returned when a blank line (no characters
before the next end of line sequence). The two cases can be distinguished by calling the chan eof
command to check for end of file. If varName is specified, the command returns -1 on end of file.
There is no ambiguity in this case because blank lines result in 0 being returned.
If a non-blocking channel is already at EOF, the command returns an empty line if varName is not
specified. This can be distinguished from an empty line being returned by either a blank line
being read or a full line not being available through the use of the chan eof and chan blocked
commands. If chan eof returns true, the channel is at EOF. If chan blocked returns true, a full
line was not available. If both commands return false, an empty line was read. If varName was
specified for a non-bocking channel at EOF, the command returns -1. This can be distinguished
from full line not being available either by chan eof or chan blocked as above. Note that when
varName is specified, there is no need to distinguish between eof and blank lines as the latter
will result in the command returning 0.
If the encoding profile strict is in effect for the channel, the command will raise an exception
with the POSIX error code EILSEQ if any encoding errors are encountered in the channel input data.
The file pointer remains unchanged and it is possible to introspect, and in some cases recover, by
changing the encoding in use"
@values -min 1 -max 2
channel
varName -optional 1
} "@doc -name Manpage: -url [manpage_tcl chan]" ]
#isbinary
#names
#pending
lappend PUNKARGS [list {
@id -id ::tcl::chan::pipe
@cmd -name "Built-in: tcl::chan::pipe"\
-summary\
"Create a standalone pipe."\
-help\
"Creates a standalone pipe whose read- and write-side channels are returned
as a 2-element list, the first element being the read side and the second
write side. Can be useful e.g. to redirect separately ${$B}stderr${$N} and ${$B}stdout${$N}
from a subprocess. To do this spawn with \"2>@\" or \">@\" redirection
operators onto the write side of a pipe, and then immediately close it
in the parent. This is necessary to get an EOF on the read side once the
child has exited or otherwise closed its output.
Note that the pipe buffering semantics can vary at the operating system
level substantially; it is not safe to assume that a write performed on
the output side of the pipe will appear instantly to the input side.
This is a fundamental difference and Tcl cannot conceal it. The overall
stream semantics ${$I}are${$NI} compatible, so blocking reads and writes
will not see most of the differences, but the details of what exactly gets
written when are not. This is most likely to show up when using pipelines
for testing; care should be taken to ensure that deadlocks do not occur
and that potential short reads are allowed for."
@values -min 0 -max 0
} "@doc -name Manpage: -url [manpage_tcl chan]" ]
lappend PUNKARGS [list {
@id -id ::tcl::chan::pop
@cmd -name "Built-in: tcl::chan::pop"\
-summary\
"Remove topmost channel transform."\
-help\
"Removes the topmost transformation from the channel ${$I}channel${$NI}, if there is any.
If there are no transformations added to channel, this is equivalent to
${$B}chan${$N} close of that channel. The result is normally the empty string, but can
be an error in some situations (i.e. where the underlying system stream is
closed and that results in an error)."
@values -min 1 -max 1
channel -type string
} "@doc -name Manpage: -url [manpage_tcl chan]" ]
lappend PUNKARGS [list {
@id -id ::tcl::chan::puts
@cmd -name "Built-in: tcl::chan::puts"\
-summary\
"Write to a channel."\
-help\
"Writes ${$I}string${$NI} to the channel named ${$I}channel${$NI} followed by a newline character. A
trailing newline character is written unless the optional flag ${$B}-nonewline${$N} is
given. If channel is omitted, the string is written to the standard output
channel, ${$B}stdout${$N}.
Newline characters in the output are translated by ${$B}chan puts${$N} to platform-specific
end-of-line sequences according to the currently configured value of the
${$B}-translation${$N} option for the channel (for example, on PCs newlines are normally
replaced with carriage-return-linefeed sequences; see ${$B}chan configure${$N} for details).
Tcl buffers output internally, so characters written with ${$B}chan puts${$N} may not appear
immediately on the output file or device; Tcl will normally delay output until the
buffer is full or the channel is closed. You can force output to appear
immediately with the ${$B}chan flush${$N} command.
When the output buffer fills up, the ${$B}chan puts${$N} command will normally block until
all the buffered data has been accepted for output by the operating system. If
channel is in non-blocking mode then the ${$B}chan puts${$N} command will not block even if
the operating system cannot accept the data. Instead, Tcl continues to buffer the
data and writes it in the background as fast as the underlying file or device can
accept it. The application must use the Tcl event loop for non-blocking output to
work; otherwise Tcl never finds out that the file or device is ready for more
output data. It is possible for an arbitrarily large amount of data to be buffered
for a channel in non-blocking mode, which could consume a large amount of memory.
To avoid wasting memory, non-blocking I/O should normally be used in an
event-driven fashion with the ${$B}chan event${$N} command (do not invoke ${$B}chan puts${$N} unless
you have recently been notified via a file event that the channel is ready for more
output data).
The command will raise an error exception with POSIX error code ${$B}EILSEQ${$N} if the
encoding profile ${$B}strict${$N} is in effect for the channel and the output data cannot be
encoded in the encoding configured for the channel. Data may be partially written
to the channel in this case."
@opts -prefix 0
-nonewline -type none
@values -min 1 -max 2
channel -type string -optional 1
string -type string
} "@doc -name Manpage: -url [manpage_tcl chan]" ]
}
lappend PUNKARGS [list {
@id -id ::tcl::chan::read
@cmd -name "Built-in: tcl::chan::read"\
-summary\
"Read from a channel."\
-help\
"In the first form, the result will be the next numChars characters read from the channel named
channel; if numChars is omitted, all characters up to the point when the channel would signal a
failure (whether an end-of-file, blocked or other error condition) are read. In the second form
(i.e. when numChars has been omitted) the flag -nonewline may be given to indicate that any
trailing newline in the string that has been read should be trimmed.
If channel is in non-blocking mode, chan read may not read as many characters as requested: once
all available input has been read, the command will return the data that is available rather
than blocking for more input. If the channel is configured to use a multi-byte encoding, then
there may actually be some bytes remaining in the internal buffers that do not form a complete
character. These bytes will not be returned until a complete character is available or end-of-file
is reached. The -nonewline switch is ignored if the command returns before reaching the end of the
file.
Chan read translates end-of-line sequences in the input into newline characters according to the
-translation option for the channel (see chan configure above for a discussion on the ways in
which chan configure will alter input).
When reading from a serial port, most applications should configure the serial port channel to be
non-blocking, like this:
chan configure channel -blocking 0
Then chan read behaves much like described above. Note that most serial ports are comparatively
slow; it is entirely possible to get a readable event for each character read from them. Care
must be taken when using chan read on blocking serial ports:
chan read channel numChars
In this form chan read blocks until numChars have been received from the serial port.
chan read channel
In this form chan read blocks until the reception of the end-of-file character, see
chan configure -eofchar. If there no end-of-file character has been configured for the
channel, then chan read will block forever.
If the encoding profile strict is in effect for the channel, the command will raise an exception
with the POSIX error code EILSEQ if any encoding errors are encountered in the channel input data.
If the channel is in blocking mode, the error is thrown after advancing the file pointer to the
beginning of the invalid data. The successfully decoded leading portion of the data prior to the
error location is returned as the value of the -data key of the error option dictionary. If the
channel is in non-blocking mode, the successfully decoded portion of data is returned by the
command without an error exception being raised. A subsequent read will start at the invalid data
and immediately raise a EILSEQ POSIX error exception. Unlike the blocking channel case, the -data
key is not present in the error option dictionary. In the case of exception thrown due to encoding
errors, it is possible to introspect, and in some cases recover, by changing the encoding in use.
See ENCODING ERROR EXAMPLES later."
@form -form readchars
@values -min 1 -max 2
channel
numChars -type integer -optional 1
@form -form read
@opts
-nonewline -type none
@values -min 1 -max 1
channel
} "@doc -name Manpage: -url [manpage_tcl chan]" ]
lappend PUNKARGS [list {
@id -id ::tcl::chan::seek
@cmd -name "Built-in: tcl::chan::seek"\
-summary\
"Set channel access position as byte offset."\
-help\
"Sets the current access position within the underlying data stream for the channel named
channel to be offset bytes relative to origin.
Offset must be an integer (which may be negative)
The origin argument defaults to start.
Chan seek flushes all buffered output for the channel before the command returns, even if the
channel is in non-blocking mode. It also discards any buffered and unread input. This command
returns an empty string. An error occurs if this command is applied to channels whose
underlying file or device does not support seeking.
Note that offset values are byte offsets, not character offsets. Both chan seek and chan tell
operate in terms of bytes, not characters, unlike chan read."
@values -min 2 -max 3
channel
offset -type integer
origin -type string\
-default start\
-optional 1\
-choicecolumns 1\
-choices {start current end}\
-choicelabels {
start\
" The new access position will be offset bytes from the start of the underlying file or device."
current\
" The new access position will be offset bytes from the current access position; a negative
offset moves the access position backwards in the underlying file or device."
enc\
" The new access position will be offset bytes from the end of the file or device. A negative
offset places the access position before the end of file, and a positive offset places the
access position after the end of file."
}
} "@doc -name Manpage: -url [manpage_tcl chan]" ]
lappend PUNKARGS [list {
@id -id ::tcl::chan::tell
@cmd -name "Built-in: tcl::chan::tell"\
-summary\
"Report channel access position as byte offset."\
-help\
"Returns a number giving the current access position within the underlying
data stream for the channel named channel. This value returned is a byte
offset that can be passed to ${[a+ bold]}chan seek${[a+ normal]} in order
to set the channel to a particular position. Note that this value is in
terms of bytes, not characters like ${[a+ bold]}chan read${[a+ normal]}. The
value returned is -1 for channels that do not support seeking."
@values -min 1 -max 1
channel -help \
""
} "@doc -name Manpage: -url [manpage_tcl chan]" ]
lappend PUNKARGS [list {
@id -id ::tcl::chan::truncate
@cmd -name "Built-in: tcl::chan::truncate"\
-summary\
"Truncate channel to specified length or current byte offset."\
-help\
"Sets the byte length of the underlying data stream for the channel to be
length (or to the current byte offset within the underlying data stream if
length is omitted). The channel is flushed before truncation."
#todo - auto synopsis?
#@form -synopsis\
# "chan truncate channel ?length?"
@values -min 1 -max 2
channel -help \
""
length -optional 1 -type integer
} "@doc -name Manpage: -url [manpage_tcl chan]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
#dict
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
namespace eval argdoc {
lappend PUNKARGS [list {
@id -id ::tcl::dict::append
@cmd -name "Built-in: tcl::dict::append" -help\
"This appends the given string (or strings) to the value that the given
key maps to in the dictionary value contained in the given variable,
writing the resulting dictionary value back to that variable. Non-existant
keys are treated as if they map to an empty string. The updated dictionary
value is returned."
@values -min 2 -max -1
dictionaryVariable -type string -help \
""
key
string -type string -optional 1 -multiple 1
} "@doc -name Manpage: -url [manpage_tcl dict]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::tcl::dict::create
@cmd -name "Built-in: tcl::dict::create" -help\
"Return a new dictionary that contains each of the key/value mappings listed
as arguments (keys and values alternating, with each key being followed by
its associated value)"
@values -min 0 -max -1
"key value" -type {string string} -typesynopsis {${$I}key${$NI} ${$I}value${$NI}} -optional 1 -multiple 1
} "@doc -name Manpage: -url [manpage_tcl dict]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::tcl::dict::exists
@cmd -name "Built-in: tcl::dict::exists" -help\
"This returns a boolean value indicating whether the given key (or path of
keys through a set of nested dictionaries) exists in the given dictionary
value. This returns a true value exactly when ${$B}dict get${$N} on that path will
succeed."
@values -min 2 -max -1
dictionaryValue -type dict
key -type string -multiple 1 -optional 0
} "@doc -name Manpage: -url [manpage_tcl dict]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::tcl::dict::for
@cmd -name "Built-in: tcl::dict::for" -help\
"This command takes three arguments, the first a two-element list of
variable names (for the key and value respectively of each mapping in
the dictionary), the second the dictionary value to iterate across, and
the third a script to be evaluated for each mapping with the key and
value variable set appropriately (in the manner of ${$B}foreach${$N}).
The result of the command is an empty string. If any evlauation of the
body generates a ${$B}TCL_BREAK${$N} result, no further pairs from the
dictionary will be iterated over and the ${$B}dict for${$N} command will
terminate successfully immediately. If any evaluation of the body generates
a ${$B}TCL_CONTINUE${$N} result, this shall be treated exactly like a
normal ${$B}TCL_OK${$N} result. The order of iteration is the order in which
the keys were inserted into the dictionary."
@values -min 3 -max 3
"{keyVariable valueVariable}" -type list -minsize 2 -maxsize 2
dictionaryValue -type dict
body -type string -help\
"Tcl script"
} "@doc -name Manpage: -url [manpage_tcl dict]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::tcl::dict::get
@cmd -name "Built-in: tcl::dict::get" -help\
"Given a dictionary value (first argument) and a key (second argument), this
will retrieve the value for that key. Where several keys are supplied, the
behaviour of the command shall be as if the result of ${$B}dict get $dictVal $key${$N}
was passed as the first argument to ${$B}dict get${$N} with the remaining
arguments as second (and possibly subsequent) arguments. This facilitates
lookups in nested dictionaries. For example, the following two commands are
equivalent:
${[punk::args::moduledoc::tclcore::argdoc::example {
dict get $dict foo bar spong
dict get [dict get [dict get $dict foo] bar] spong\
}
]}
If no keys are provided, ${$B}dict get${$N} will return a list containing pairs
of elements in a manner similar to ${$B}array get${$N}. That is, the first
element of each pair would be the key and the second element would be the value
for that key.
It is an error to attempt to retrieve a value for a key that is not present in
the dictionary.
"
@values -min 1 -max -1
dictionaryValue -type dict
key -type string -multiple 1 -optional 1
} "@doc -name Manpage: -url [manpage_tcl dict]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::tcl::dict::getdef
@cmd -name "Built-in: tcl::dict::getdef" -help\
"This behaves the same as ${$B}dict get${$N} (with at least one ${$I}key${$NI} argument),
returning the value that the key path maps to in the dictionary
${$I}dictionaryValue${$NI}, except that instead of producing an error because the
${$I}key${$NI} (or one of the ${$I}key${$NI}s on the key path) is absent, it returns the
${$I}default${$NI} argument instead.
Note that there must always be at least one ${$I}key${$NI} provided, and that ${$B}dict getdef${$N} and
${$B}dict getwithdefault${$N} are aliases for each other."
@values -min 1 -max -1
dictionaryValue -type dict
key -type string -multiple 1 -optional 0
default -type any -optional 0
} "@doc -name Manpage: -url [manpage_tcl dict]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
#use getdef to define getwithdefault
punk::args::define [punk::args::resolved_def -override {@id {
-id ::tcl::dict::getwithdefault
} @cmd {
-name "Built-in: tcl::dict::getwithdefault"
}} ::tcl::dict::getdef]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::tcl::dict::incr
@cmd -name "Built-in: tcl::dict::incr" -help\
"This adds the given ${$I}increment${$NI} value (an integer that defaults to 1 if
not specified) to the value that the given key maps to in the dictionary
value contained in the given variable, writing the resulting dictionary
value back to that variable. Non-existent keys are treated as if they
map to 0. It is an error to increment a value for an existing key if that
value is not an integer. The updated dictionary value is returned. If
${$I}dictionaryVariable${$NI} indicates an element that does not exist of an array
that has a default value set, the default value and will be used as the
value of the dictionary prior to the incrementing operation."
@values -min 2 -max 3
dictionaryVariable -type string
key -type any
increment -type integer -default 1 -optional 1
} "@doc -name Manpage: -url [manpage_tcl dict]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::tcl::dict::info
@cmd -name "Built-in: tcl::dict::info" -help\
"This returns information (intended for display to people) about the
given dictionary though the format of this data is dependent on the
implementation of the dictionary. For dictionaries that are implemented
by hash tables, it is expected that this will return the string produced
by ${$B}Tcl_HashStats${$N}, similar to ${$B}array statistics${$N}."
@values -min 1 -max 1
dictionaryValue -type dict
} "@doc -name Manpage: -url [manpage_tcl dict]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::tcl::dict::keys
@cmd -name "Built-in: tcl::dict::keys" -help\
"Return a list of all keys in the given dictionary value. If a pattern is
supplied, only those keys that match it (according to the rules of ${$B}string
match${$N}) will be returned. The returned keys will be in the order that they
were inserted into the dictionary."
@values -min 1 -max 2
dictionaryValue -type dict
globPattern -type string -optional 1
} "@doc -name Manpage: -url [manpage_tcl dict]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::tcl::dict::lappend
@cmd -name "Built-in: tcl::dict::lappend" -help\
"This appends the given items to the list value that the given key maps
to in the dictionary value contained in the given variable, writing the
resulting dictionary value back to that variable. Non-existent keys are
treated as if they map to an empty list, and it is legal for there to be
no items to append to the list. It is an error for the value that the key
maps to to not be representable as a list. The updated dictionary value
is returned. If ${$I}dictionaryVariable${$NI} indicates an element that does not
exist of an array that has a default value set, the default value and
will be used as the value of the dictionary prior to the list-appending
operation."
@values -min 2 -max -1
dictionaryVariable -type dict
key -type any
value -type any -multiple 1 -optional 1
} "@doc -name Manpage: -url [manpage_tcl dict]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::tcl::dict::map
@cmd -name "Built-in: tcl::dict::map" -help\
"This command applies a transformation to each element of a dictionary,
returning a new dictionary. It takes three arguments: the first is a
two-element list of variable names (for the key and value respectively of
each mapping in the dictionary), the second the dictionary value to
iterate across, and the third a script to be evaluated for each mapping
with the key and value variables set appropriately (in the manner of ${$B}lmap${$N}).
In an iteration where the evaluated script completes normally (${$B}TCL_OK${$N}, as
opposed to an ${$B}error${$N}, etc.) the result of the script is put into an
accumulator dictionary using the key that is the current contents of the
keyVariable variable at that point. The result of the ${$B}dict map${$N} command is
the accumulator dictionary after all keys have been iterated over.
If the evaluation of the body for any particular step generates a break,
no further pairs from the dictionary will be iterated over and the ${$B}dict
map${$N} command will terminate successfully immediately. If the evaluation of
the body for a particular step generates a continue result, the current
iteration is aborted and the accumulator dictionary is not modified. The
order of iteration is the natural order of the dictionary (typically the
order in which the keys were added to the dictionary; the order is the
same as that used in ${$B}dict for${$N})."
@values -min 3 -max 3
"{keyVariable valueVariable}" -type list -minsize 2 -maxsize 2
dictionaryValue -type dict
body -type script
} "@doc -name Manpage: -url [manpage_tcl dict]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::tcl::dict::merge
@cmd -name "Built-in: tcl::dict::merge" -help\
"Return a dictionary that contains the contents of each of the
${$I}dictionaryValue${$NI} arguments. Where two (or more) dictionaries
contain a mapping for the same key, the resulting dictionary maps that
key to the value according to the last dictionary on the command line
containing a mapping for that key."
@values -min 0 -max -1
dictionaryValue -type dict -optional 1 -multiple 1
} "@doc -name Manpage: -url [manpage_tcl dict]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::tcl::dict::remove
@cmd -name "Built-in: tcl::dict::remove" -help\
"Return a new dictionary that is a copy of an old one passed in as first
argument except without mappings for each of the keys listed. It is legal
for there to be no keys to remove, and it also legal for any of the keys
to be removed to not be present in the input dictionary in the first place."
@values -min 1 -max -1
dictionaryValue -type dict
key -type any -optional 1 -multiple 1
} "@doc -name Manpage: -url [manpage_tcl dict]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::tcl::dict::replace
@cmd -name "Built-in: tcl::dict::replace" -help\
"Return a new dictionary that is a copy of an old one passed in as first
argument except with some values different or some extra key/value pairs
added. It is legal for this command to be called with no key/value pairs,
but illegal for this command to be called with a key but no value."
@values -min 1 -max -1
dictionaryValue -type dict
"key value" -type {any any} -optional 1 -multiple 1
} "@doc -name Manpage: -url [manpage_tcl dict]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::tcl::dict::set
@cmd -name "Built-in: tcl::dict::set" -help\
"This operation takes the name of a variable containing a dictionary value
and places an updated dictionary value in that variable containing a
mapping from the given key to the given value. When multiple keys are
present, this operation creates or updates a chain of nested dictionaries.
The updated dictionary value is returned. If ${$I}dictionaryVariable${$NI} indicates
an element that does not exist of an array that has a default value set,
the default value and will be used as the value of the dictionary prior to
the value insert/update operation."
@values -min 3 -max -1
dictionaryVariable -type string
key -type string -optional 0 -multiple 1
value -type any
} "@doc -name Manpage: -url [manpage_tcl dict]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::tcl::dict::size
@cmd -name "Built-in: tcl::dict::size" -help\
"Return the number of key/value mappings in the given dictionary value."
@values -min 1 -max 1
dictionaryValue -type dict
} "@doc -name Manpage: -url [manpage_tcl dict]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::tcl::dict::unset
@cmd -name "Built-in: tcl::dict::unset" -help\
"This operation (the companion to ${$B}dict set${$NI}) takes the name of a variable
containing a dictionary value and places an updated dictionary value in
that variable that does not contain a mapping for the given key. Where
multiple keys are present, this describes a path through nested
dictionaries to the mapping to remove. At least one key must be specified,
but the last key on the key-path need not exist. All other components on
the path must exist. The updated dictionary value is returned. If
${$I}dictionaryVariable${$NI} indicates an element that does not exist of an array
that has a default value set, the default value and will be used as the
value of the dictionary prior to the value remove operation."
@values -min 2 -max -1
dictionaryVariable -type string
key -type string -optional 0 -multiple 1
} "@doc -name Manpage: -url [manpage_tcl dict]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::tcl::dict::update
@cmd -name "Built-in: tcl::dict::update" -help\
"Execute the Tcl script in ${$I}body${$NI} with the value for each ${$I}key${$NI} (as found by
reading the dictionary value in ${$I}dictionaryVariable${$NI}) mapped to the variable
${$I}varName${$NI}. There may be multiple ${$I}key/varName${$NI} pairs. If a ${$I}key${$NI} does not have a
mapping, that corresponds to an unset ${$I}varName${$NI}. When ${$I}body${$NI} terminates, any
changes made to the ${$I}varName${$NI}s is reflected back to the dictionary within
${$I}dictionaryVariable${$NI} (unless ${$I}dictionaryVariable${$NI} itself becomes unreadable,
when all updates are silently discarded), even if the result of ${$I}body${$NI} is an
error or some other kind of exceptional exit. The result of dict update is
(unless some kind of error occurs) the result of the evaluation of ${$I}body${$NI}.
If ${$I}dictionaryVariable${$NI} indicates an element that does not exist of an array
that has a default value set, the default value and will be used as the
value of the dictionary prior to the update operation.
Each ${$I}varName${$NI} is mapped in the scope enclosing the dict update; it is
recommended that this command only be used in a local scope (${$B}proc${$N}edure,
lambda term for ${$B}apply${$N}, or method). Because of this, the variables set by
${$B}dict update${$N} will continue to exist after the command finishes (unless
explicitly unset).
Note that the mapping of values to variables does not use traces; changes
to the ${$I}dictionaryVariable${$NI}'s contents only happen when ${$I}body${$NI} terminates."
@values -min 4 -max -1
dictionaryVariable -type string
"key varName" -type {any any} -typesynopsis {${$I}key${$NI} ${$I}varName${$NI}} -optional 0 -multiple 1
body -type script -typesynopsis ${$I}body<script>${$NI} -optional 0
} "@doc -name Manpage: -url [manpage_tcl dict]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::tcl::dict::with
@cmd -name "Built-in: tcl::dict::with" -help\
"Execute the Tcl script in body with the value for each key in dictionaryVariable mapped (in a manner
similarly to dict update) to a variable with the same name. Where one or more keys are available,
these indicate a chain of nested dictionaries, with the innermost dictionary being the one opened out
for the execution of body. As with dict update, making dictionaryVariable unreadable will make the
updates to the dictionary be discarded, and this also happens if the contents of dictionaryVariable
are adjusted so that the chain of dictionaries no longer exists. The result of dict with is (unless
some kind of error occurs) the result of the evaluation of body. If dictionaryVariable indicates an
element that does not exist of an array that has a default value set, the default value and will be
used as the value of the dictionary prior to the updating operation.
The variables are mapped in the scope enclosing the dict with; it is recommended that this command
only be used in a local scope (procedure, lambda term for apply, or method). Because of this, the
variables set by dict with will continue to exist after the command finishes (unless explicitly unset).
Note that the mapping of values to variables does not use traces; changes to the dictionaryVariable's
contents only happen when body terminates.
If the dictionaryVariable contains a value that is not a dictionary at the point when the body
terminates (which can easily happen if the name is the same as any of the keys in dictionary) then an
error occurs at that point. This command is thus not recommended for use when the keys in the
dictionary are expected to clash with the dictionaryVariable name itself. Where the contained key does
map to a dictionary, the net effect is to combine that inner dictionary into the outer dictionary; see
the EXAMPLES for an illustration of this."
@values -min 2 -max -1
dictionaryVariable -type string
key -type any -typesynopsis {${$I}key${$NI}} -optional 1 -multiple 1
body -type script -typesynopsis ${$I}body<script>${$NI} -optional 0
} "@doc -name Manpage: -url [manpage_tcl dict]" ]
}
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
#file
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
namespace eval argdoc {
lappend PUNKARGS [list {
@id -id ::tcl::file::channels
@cmd -name "Built-in: tcl::file::channels" -help\
"If ${$I}pattern${$NI} is not specified, returns a list of names of all
registered copen channels in this interpreter. If ${$I}pattern${$NI} is
specified, only those names matching ${$I}pattern${$NI} are returned.
Matching is determined using the same rules as for string match."
@opts -prefix 0
@values -min 0 -max -1
pattern -optional 1 -type string -default *
} "@doc -name Manpage: -url [manpage_tcl file]" ]
lappend PUNKARGS [list {
@id -id ::tcl::file::delete
@cmd -name "Built-in: tcl::file::delete" -help\
"Removes the file or directory specified by each ${$I}pathname${$NI} argument.
Non-empty directories will be removed only if the ${$B}-force${$N} option is
specified. When operating on symbolic links, the links themselves will be
deleted, not the objects they point to. Trying to delete a non-existent file
is not considered an error. Trying to delete a read-only file will cause the
file to be deleted, even if the ${$B}-force${$N} flag is not specified. If the ${$B}-force${$N}
flag is specified on a directory, Tcl will attempt both to change permissions
and move the current directory \"pwd\" out of the given path if that is
necessary to allow the deletion to proceed. Arguments are processed in the
order specified, halting at the first error, if any. A -- marks the end of
switches; the argument following the -- will be treated as a ${$I}pathname${$NI}
even if it starts with a -."
@opts -prefix 0
-force -optional 1 -type none
-- -optional 1 -type none
@values -min 0 -max -1
pathname -optional 1 -type string -multiple 1
} "@doc -name Manpage: -url [manpage_tcl file]" ]
lappend PUNKARGS [list {
@id -id ::tcl::file::copy
@cmd -name "Built-in: tcl::file::copy" -help\
"The first form makes a copy of the file or directory ${$I}source${$NI} under the pathname ${$I}target${$NI}.
If ${$I}target${$NI} is an existing directory then the second form is used.
The second form makes a copy inside ${$I}targetDir${$NI} of each ${$I}source${$NI} file listed.
If a directory is specified as a ${$I}source${$NI}, then the contents of the directory will be
recursiveley copied into ${$I}targetDir${$NI}. Existing files will not be overwritten unless the
${$B}-force${$N} options is specified (when Tcl will also attempt to adjust permissions on the destination
file or directory if that is necessary to allow the copy to proceed).
When copying within a single filesystem, ${$I}file copy${$NI} will copy soft links (i.e the links themselves
are copied, not the things they point to.) Trying to overwrite a non-empty directory, overwrite a directory
with a file, or overwrite a file with a directory will all result in errors even if ${$B}-force${$N} was
specified.
Arguments are processed in the order specified, halting at the first error, if any. A -- marks the end of
switches; the argument following the -- will be treated as a ${$I}source${$NI} even if it starts with a -."
@form -form {topath inpath}
@opts -form {*} -prefix 0
-force -optional 1 -type none
-- -optional 1 -type none
@form -form "topath"
@values -min 2 -max 2
source -type string -help\
"file or directory"
target -type string
@form -form "inpath"
@values -min 2 -max -1
source -type string -multiple 1 -help\
"file or directory"
targetDir -optional 0 -type existingdir
} "@doc -name Manpage: -url [manpage_tcl file]" ]
lappend PUNKARGS [list {
@id -id ::tcl::file::executable
@cmd -name "Built-in: tcl::file::executable" -help\
"Returns ${$B}1${$N} if file ${$I}name${$NI} is executable by the current user, ${$B}0${$N}
otherwise. On Windows, which does not have an executable attribute, the command treats
all directories and any files with extensions ${$B}exe${$N}, ${$B}com${$N}, ${$B}cmd${$N} or ${$B}bat${$N} as executable."
@values -min 0 -max 1
name -type string
} "@doc -name Manpage: -url [manpage_tcl file]" ]
lappend PUNKARGS [list {
@id -id ::tcl::file::exists
@cmd -name "Built-in: tcl::file::exists" -help\
"Returns ${$B}1${$N} if the file ${$I}name${$NI} exists and the current user has search
privileges for the directories leading to it, ${$B}0${$N} otherwise."
@values -min 0 -max 1
name -type string
} "@doc -name Manpage: -url [manpage_tcl file]" ]
lappend PUNKARGS [list {
@id -id ::tcl::file::extension
@cmd -name "Built-in: tcl::file::extension" -help\
"Returns all of the characters in ${$I}name${$NI} after and including the last dot in the last
element of name. If there is no dot in the last element of ${$I}name${$NI} then returns the
empty string."
@values -min 0 -max 1
name -type string
} "@doc -name Manpage: -url [manpage_tcl file]" ]
lappend PUNKARGS [list {
@id -id ::tcl::file::home
@cmd -name "Built-in: tcl::file::home" -help\
"If no argument is specified, the command returns the home directory of the current user.
This is generally the value of the ${$B}$HOME${$N} environment variable except that on Windows
platforms backslashes in the path are replaced by forward slashes. An error is raised if
the ${$B}$HOME${$N} environment variable is not set.
if ${$I}username${$NI} is specified, the command returns the home directory configured in the
system for the specified user. Note this may be different that the value of the ${$B}$HOME${$N}
environment variable even when the ${$I}username${$NI} corresponds to the current user.
An error is raised if the ${$I}username${$NI} does not correspond to a user account on the system."
@values -min 0 -max 1
username -optional 1 -type string
} "@doc -name Manpage: -url [manpage_tcl file]" ]
lappend PUNKARGS [list {
@id -id ::tcl::file::isdirectory
@cmd -name "Built-in: tcl::file::isdirectory" -help\
"Returns ${$B}1${$N} if the file name is a directory, ${$B}0${$N} otherwise."
@values -min 1 -max 1
name -optional 0 -type string
} "@doc -name Manpage: -url [manpage_tcl file]" ]
lappend PUNKARGS [list {
@id -id ::tcl::file::isfile
@cmd -name "Built-in: tcl::file::isfile" -help\
"Returns ${$B}1${$N} if the file name is a regular file, ${$B}0${$N} otherwise."
@values -min 1 -max 1
name -optional 0 -type string
} "@doc -name Manpage: -url [manpage_tcl file]" ]
#join
#link
#lstat
lappend PUNKARGS [list {
@id -id ::tcl::file::mkdir
@cmd -name "Built-in: tcl::file::mkdir" -help\
"Creates each directory specified.
For each pathname ${$I}dir${$NI} specified, this command will create all non-existing parent directories
as well as ${$I}dir${$NI} itself. If an existing directory is specified, then no action is taken and no
error is returned. Trying to overwrite an existing file with a directory will result in an error.
Arguments are processed in the order specified, halting at the first error, if any."
@values -min 0 -max -1
dir -optional 1 -type string -multiple 1
#dir -optional 1 -type directory -multiple 1
} "@doc -name Manpage: -url [manpage_tcl file]" ]
lappend PUNKARGS [list {
@id -id ::tcl::file::mtime
@cmd -name "Built-in: tcl::file::mtime" -help\
"Returns a decimal string giving the time at which file ${$I}name${$NI} was last modified.
If ${$I}time${$NI} is specified, it is a modification time to set for the file (equivalent
to Unix ${$B}touch${$N}). The time is measured in the standard POSIX fashion as seconds
from a fixed starting time (often January 1, 1970). If the file does not exist or its
modified time cannot be queried or set then an error is generated. on ${$B}zipfs${$N}
file systems, modification time cannot be explicitly set."
@values -min 1 -max 2
name -type string
time -type integer -optional 1
} "@doc -name Manpage: -url [manpage_tcl file]"]
#nativename
#normalize
#owned
#pathtype
lappend PUNKARGS [list {
@id -id ::tcl::file::readable
@cmd -name "Built-in: tcl::file::readable" -help\
"Returns ${$B}1${$N} if the file ${$I}name${$NI} is readable by the current user, ${$B}0${$N} otherwise."
@values -min 1 -max 1
name -optional 0 -type string
} "@doc -name Manpage: -url [manpage_tcl file]"]
#readlink
#rename (2 forms)
#rootname
#separator
#size
#split
#stat
#system
#tail
#tempdir
#tempfile
#tildeexpand
#type
#volumes
lappend PUNKARGS [list {
@id -id ::tcl::file::writable
@cmd -name "Built-in: tcl::file::writable" -help\
"Returns ${$B}1${$N} if the file ${$I}name${$NI} is writable by the current user, ${$B}0${$N} otherwise."
@values -min 1 -max 1
name -optional 0 -type string
} "@doc -name Manpage: -url [manpage_tcl file]"]
}
namespace eval argdoc {
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::tcl::mathfunc::abs
@cmd -name "Built-in: tcl::mathfunc::abs" -help\
"Returns the absolute value of ${$I}arg${$NI}. ${$I}Arg${$NI} may be either integer
or floating-point, and the result is returned in the same form."
@values -min 1 -max 1
#review - NaN shouldn't be accepted - specify a range to exclude it.
arg -type number -range {-Inf Inf}
} "@doc -name Manpage: -url [manpage_tcl mathfunc]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::tcl::mathfunc::acos
@cmd -name "Built-in: tcl::mathfunc::acos" -help\
"Returns the arc cosine of ${$I}arg${$NI}, in the range [0,pi] radians.
${$I}Arg${$NI} should be in the range [-1,1]."
@values -min 1 -max 1
arg -type number -range {-1 1}
} "@doc -name Manpage: -url [manpage_tcl mathfunc]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
#asin
#atan
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::tcl::mathfunc::atan2
@cmd -name "Built-in: tcl::mathfunc::atan2" -help\
"Returns the arc tangent of ${$I}y/x${$NI}, in the range [-pi,pi] radians.
${$I}x${$NI} and ${$I}y${$NI} cannot both be 0. If ${$I}x${$NI} is greater
than 0, this is equivalent to \"${$B}atan [expr {y/x}]${$N}\"."
@values -min 2 -max 2
y -type number
x -type number
} "@doc -name Manpage: -url [manpage_tcl mathfunc]" ]
}
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::tcl::namespace::children
@cmd -name "Built-in: tcl::namespace::children"\
-summary\
"list child namespaces"\
-help\
"Returns a list of all child namespaces that belong to the namespace namespace.
If namespace is not specified, then the children are returned for the current
namespace. This command returns fully-qualified names, which start with a double
colon (::). If the optional pattern is given, then this command returns only the
names that match the glob-style pattern. The actual pattern used is determined as
follows: a pattern that starts with double colon (::) is used directly, otherwise
the namespace namespace (or the fully-qualified name of the current namespace) is
prepended onto the pattern."
@values
namespace -optional 1
pattern -optional 1
} "@doc -name Manpage: -url [manpage_tcl namespace]" ]
lappend PUNKARGS [list {
@id -id ::tcl::namespace::origin
@cmd -name "Built-in: tcl::namespace::origin" -help\
"Returns the fully-qualified name of the original command to which the
imported command command refers. When a command is imported into a
namespace, a new command is created in that namespace that points to the
actual command in the exporting namespace. If a command is imported into
a sequence of namespaces a,b,...,n where each successive namespace just
imports the command from the previous namespace, this command returns
the fully-qualified name of the original command in the first namespace, a.
If command does not refer to an imported command, the command's own
fully-qualified name is returned
"
@values
command
} "@doc -name Manpage: -url [manpage_tcl namespace]" ]
lappend PUNKARGS [list {
@id -id ::tcl::namespace::path
@cmd -name "Built-in: tcl::namespace::path" -help\
"Returns the command resolution path of the current namespace.
If namespaceList is specified as a list of named namespaces, the current
namespace's command resolution path is set to those namespaces and returns
the empty list. The default command resolution path is always empty.
See the section NAME_RESOLUTION in the manpage for an explanation of the
rules regarding name resolution."
@values -min 0 -max 1
namespaceList -type list -optional 1 -help\
"List of existing namespaces"
} "@doc -name Manpage: -url [manpage_tcl namespace]" ]
lappend PUNKARGS [list {
@id -id ::tcl::namespace::unknown
@cmd -name "Built-in: tcl::namespace::unknown" -help\
"Sets or returns the unknown command handler for the current namespace.
The handler is invoked when a command called from within the namespace cannot
be found in the current namespace, the namespace's path nor in the global
namespace.
When the handler is invoked, the full invocation line will be appended to
the script and the result evaluated in the context of the namespace.
The default handler for all namespaces is ${[a+ italic]}::unknown${[a+ noitalic]}.
If no argument is given, it returns the handler for the current namespace."
@values -min 0 -max 1
script -type script -optional 1 -help\
"A well formed list representing a command name and optional arguments."
} "@doc -name Manpage: -url [manpage_tcl namespace]" ]
lappend PUNKARGS [list {
@id -id ::tcl::namespace::which
@cmd -name "Built-in: tcl::namespace::which" -help\
"Looks up name as either a command or variable and returns its fully-qulified name.
For example, if name does not exist in the current namespace but does exist in the
global namespace, this command returns a fully-qualified name in the global namespace.
If the command or variable does not exist, this command returns an empty string. If
the variable has been created but not defined, such as with the variable command or
through a trace on the variable, this command will return the fully-qualified name
of the variable. If no flag is given, name is treated as a command name.
See the section NAME RESOLUTION in the manpage for an explanation of the rules
regarding name resolution.
"
@leaders -min 0 -max 1
option -type {literalprefix(-command)|literalprefix(-variable)} -optional 1 -choices {-command -variable}
#@opts
#-command -type none
##todo - make mutually exclusive - (separate forms)
#-variable -type none
#@values -min 1 -max 1
name
} "@doc -name Manpage: -url [manpage_tcl namespace]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
namespace eval argdoc {
#JJJ
#define tcl::prefix::* subcommand documentation first
lappend PUNKARGS [list {
@id -id ::tcl::prefix::all
@cmd -name "Built-in: tcl::prefix::all"\
-summary\
"List all in table that begin with ${$I}string${$NI}"\
-help\
"Returns a list of all elements in table that begin with the prefix string."
@values -min 2 -max 2
table -type list
string -type string
} "@doc -name Manpage: -url [manpage_tcl prefix]" ]
lappend PUNKARGS [list {
@id -id ::tcl::prefix::longest
@cmd -name "Built-in: tcl::prefix::longest"\
-summary\
"longest common prefix of table elements that begin with ${$I}string${$NI}"\
-help\
"Returns the longest common prefix of all elements in table that begin with the prefix ${$I}string${$NI}"
@values -min 2 -max 2
table -type list
string -type string
} "@doc -name Manpage: -url [manpage_tcl prefix]" ]
lappend PUNKARGS [list {
@id -id ::tcl::prefix::match
@cmd -name "Built-in: tcl::prefix::match"\
-summary\
"match one element in table to prefix ${$I}string${$NI}"\
-help\
"If string equals one element in table or is a prefix to exactly one element, the matched
element is returned. If not, the result depends on the -error option. (It is recommended
that the table be sorted before use with this subcommand, so that the list of matches
presented in the error message also becomes sorted, though this is not strictly necessary
for the operation of this subcommand itself.)"
@opts
-exact -type none -help\
"Accept only exact matches"
-message -type string -default option -help\
"Use ${$I}string${$NI} in the error message at a mismatch. Default is option."
-error -type list -typesynopsis ${$I}options${$NI} -help\
"The options are used when no match is found. If options is empty, no error is
generated and an empty string is returned. Otherwise the options are used as
return options when generating the error message. The default corresponds to
setting -level 0.
Example: If -error {-errorcode MyError -level 1} is used, an error would be
generated as:
return -errorcode MyError -level 1 -code error \"ambiguous option ...\""
@values -min 2 -max 2
table -type list
string -type string
} "@doc -name Manpage: -url [manpage_tcl prefix]" ]
# ---------------------------------------------------------------------------------------------------------------------------
proc tclprefix_subcommands {} {
dict set groups "" {all longest match}
return [punk::args::ensemble_subcommands_definition -groupdict $groups -columns 1 tcl::prefix]
}
set DYN_TCLPREFIX_SUBCOMMANDS {${[punk::args::moduledoc::tclcore::argdoc::tclprefix_subcommands]}}
lappend PUNKARGS [list {
@dynamic
@id -id ::tcl::prefix
@cmd -name "Built-in: tcl::prefix"\
-summary\
"Facilities for prefix matching"\
-help\
"Facilities for prefix matching"
@leaders -min 1 -max 1
${$DYN_TCLPREFIX_SUBCOMMANDS}
@values -unnamed true
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl prefix]" \
{@examples -help {
Basic use:
${[punk::args::moduledoc::tclcore::argdoc::example {
namespace import ::tcl::prefix
prefix match {apa bepa cepa} apa
apa
prefix match {apa bepa cepa} a
apa
prefix match -exact {apa bepa cepa} a
bad option "a": must be apa, bepa, or cepa
prefix match -message "switch" {apa ada bepa cepa} a
ambiguous switch "a": must be apa, ada, bepa, or cepa
prefix longest {fblocked fconfigure fcopy file fileevent flush} fc
fco
prefix all {fblocked fconfigure fcopy file fileevent flush} fc
fconfigure fcopy
}]}
Simplifying option matching:
${[punk::args::moduledoc::tclcore::argdoc::example {
array set opts {-apa 1 -bepa "" -cepa 0}
foreach {arg val} $args {
set opts([prefix match {-apa -bepa -cepa} $arg]) $val
}
}]}
Creating a switch that supports prefixes:
${[punk::args::moduledoc::tclcore::argdoc::example {
switch [prefix match {apa bepa cepa} $arg] {
apa { }
bepa { }
cepa { }
}
}]}
}
}]
# ---------------------------------------------------------------------------------------------------------------------------
}
#
lappend PUNKARGS [list {
@id -id ::tcl::process::status
@cmd -name "Built-in: tcl::process::status" -help\
"Returns a dictionary mapping subprocess PIDs to their respective status.
If ${$I}pids${$NI} is specified as a list of PIDs then the command
only returns the status of the matching subprocesses if they exist.
For active processes, the status is an empty value. For terminated
processes, the status is a list with the following format:
{code ?msg errorCode?}
where:
${$I}code${$NI}
is a standard Tcl return code, ie.,
0 for TCL_OK and 1 for TCL_ERROR,
${$I}msg${$NI}
is the human readable error message,
${$I}errorCode${$NI}
uses the same format as the errorCode global variable
Note that msg and errorCode are only present for abnormally
terminated processes (i.e. those where the code is nonzero).
Under the hood this command calls Tcl_WaitPid with the
WNOHANG flag set for non-blocking behaviour, unless the -wait
switch is set (see below).
"
-wait -type none -optional 1 -help\
"By default the command returns immediately (the underlying Tcl_WaitPid
is called with the WNOHANG flag set) unless this switch is set. if pids
is specified as a list of PIDS then the command waits until the status
of the matching subprocesses are avaliable. If pids was not specified,
this command will wait for all known subprocesses."
-- -type none -optional 1 -help\
"Marks the end of switches. The argument following this one will be
treated as the first arg even if it starts with a -."
@values -min 0 -max 1
pids -type list -optional 1 -help\
"A list of PIDs"
} "@doc -name Manpage: -url [manpage_tcl namespace]" ]
lappend PUNKARGS [list {
@id -id ::tcl::process::purge
@cmd -name "Built-in: tcl::process::purge" -help\
"Cleans up all data associated with terminated subprocesses. If pids is
specified as a list of PIDs then the command only cleans up data for
the matching subprocesses if they exist. If a process listed is still
active, this command does nothing to that process.
Any PID that does not correspond to a subprocess is ignored."
@values -min 0 -max 1
pids -type list -optional 1 -help\
"A list of PIDs"
} "@doc -name Manpage: -url [manpage_tcl namespace]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
############################################################################################################################################################
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# COMMANDS A-H
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
############################################################################################################################################################
lappend PUNKARGS [list {
#test of @form
@id -id ::after
@cmd -name "Built-in: after"\
-summary\
"Execute a command after a time delay."\
-help\
"This command is used to delay execution of the program or to execute a
command in background sometime in the future.
The after ms and after idle forms of the command assume that the application
is event driven: the delayed commands will not be executed unless the
application enters the event loop. In applications that are not normally
event-driven, such as tclsh, the event loop can be entered with the vwait
and update commands."
# ---------- shared elements -------------
@ref -id common_script_help -help\
"script argument to be concatenated in the same fashion as the concat command"
# ---------- shared elements -------------
#@form -form {delay} -synopsis "after ms"
@form -form {delay}
#@form -form {schedule_ms} -synopsis "after ms ?script...?"
@form -form {schedule_ms}
#review
#@values -form {*} #note "classify next argument as a value not a leader"
#@values -form {*}
@leaders -form {delay schedule_ms} -min 1 -max 1
ms -form {*} -type int -help\
"milliseconds"
@values -form {delay} -min 0 -max 0
@values -form {schedule_ms} -min 1
script -form {schedule_ms} -multiple 1 -optional 0 ref-help common_script_help
#@form -form {cancelid} -synopsis "after cancel id"
@form -form {cancelid}
@leaders -min 1 -max 1
cancel -choices {cancel}
@values -min 1 -max 1
id
#@form -form {cancelscript} -synopsis "after cancel script ?script...?"
@form -form {cancelscript}
@leaders
cancel -choices {cancel}
@values -min 1
script -multiple 1 -optional 0 ref-help common_script_help
#@form -form {schedule_idle} -synopsis "after idle script ?script...?"
@form -form {schedule_idle}
@leaders -min 1 -max 1
idle -choices {idle} -choiceprefixreservelist {info}
@values -min 1
script -multiple 1 -optional 0 ref-help common_script_help
#@form -form {info} -synopsis "after info ?id?"
@form -form {info}
@leaders -min 1 -max 1
info -choices {info} -choiceprefixreservelist {idle}
@values -min 0 -max 1
id -optional 1
} "@doc -name Manpage: -url [manpage_tcl after]" ]
namespace eval argdoc {
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::append
@cmd -name "Built-in: append"\
-summary\
"Append to variable."\
-help\
"Append all of the ${$I}value${$NI} arguments to the current value of variable
${$I}varName${$NI}. if ${$I}varName${$NI} does not exist, it is given a value equal
to the concatenation of all the ${$I}value${$NI} arguments.
if ${$I}varName indicates an element that does not exist of an array that has a default value
set, the concatenation of the default value and all the ${$I}value${$NI} arguments will be stored
in the array element.
The result of this command is the new value stored in variable ${$I}varName${$NI}.
This command privides an efficient way to build up long variables incrementally.
For example, \"${$B}append a $b${$N}\" is much more efficient than \"${$B}set a $a$b${$N}\"
if ${$B}$a${$N} is long."
@values -min 1
varName -optional 0
value -type string -optional 1 -multiple 1
} "@doc -name Manpage: -url [manpage_tcl append]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::apply
@cmd -name "Built-in: apply"\
-summary\
{Apply an anonymous function.}\
-help\
{The command ${$B}apply${$N} applies the function ${$I}func${$NI} to the arguments arg1 arg2 ...
and returns the result.
The function func is a two element list {${$I}args body${$NI}} or a three element list
{${$I}args body namespace${$NI}} (as if the list command had been used). The first
element ${$I}args${$NI} specifies the formal arguments to func. The specification of
the formal arguments ${$I}args${$NI} is shared with the ${$B}proc${$N} command, and is described
in detail in the corresponding manual page.
The contents of ${$I}body${$NI} are executed by the Tcl interpreter after the local
variables corresponding to the formal arguments are given the values of the
actual parameters arg1 arg2 .... When ${$I}body${$NI} is being executed, variable names
normally refer to local variables, which are created automatically when
referenced and deleted when ${$B}apply${$N} returns. One local variable is automatically
created for each of the function's arguments. Global variables can only be
accessed by invoking the ${$B}global${$N} command or the ${$B}upvar${$N} command. Namespace
variables can only be accessed by invoking the ${$B}variable${$N} command or the ${$B}upvar${$N}
command.
The invocation of ${$B}apply${$N} adds a call frame to Tcl's evaluation stack (the stack
of frames accessed via ${$B}uplevel${$N}). The execution of ${$I}body${$NI} proceeds in this call
frame, in the namespace given by ${$I}namespace${$NI} or in the global namespace if none
was specified. If given, ${$I}namespace${$NI} is interpreted relative to the global
namespace even if its name does not start with ::.
The semantics of ${$B}apply${$N} can also be described by approximately this:
${[punk::args::moduledoc::tclcore::argdoc::example {
proc apply {fun args} {
set len [llength $fun]
if {($len < 2) || ($len > 3)} {
error "can't interpret \"$fun\" as anonymous function"
}
lassign $fun argList body ns
set name ::$ns::[getGloballyUniqueName]
set body0 {
rename [lindex [info level 0] 0] {}
}
proc $name $argList ${body0}$body
set code [catch {uplevel 1 $name $args} res opt]
return -options $opt $res
}}]}
}
@values -min 1
"{args body ?namespace?}" -optional 0 -type list -minsize 2 -maxsize 3
arg -type any -optional 1 -multiple 1
} "@doc -name Manpage: -url [manpage_tcl append]"\
{@examples -help {
This shows how to make a simple general command that applies a transformation to each element of a list.
${[punk::args::moduledoc::tclcore::argdoc::example {
proc map {lambda list} {
set result {}
foreach item $list {
lappend result [apply $lambda $item]
}
return $result
}
map {x {return [string length $x]:$x}} {a bb ccc dddd}
1:a 2:bb 3:ccc 4:dddd
map {x {expr {$x**2 + 3*$x - 2}}} {-4 -3 -2 -1 0 1 2 3 4}
2 -2 -4 -4 -2 2 8 16 26
}]}
The apply command is also useful for defining callbacks for use in the trace command:
${[punk::args::moduledoc::tclcore::argdoc::example {
set vbl "123abc"
trace add variable vbl write {apply {{v1 v2 op} {
upvar 1 $v1 v
puts "updated variable to \"$v\""
}}}
set vbl 123
set vbl abc
}]}
}
}
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
#categorise array subcommands based on currently known groupings.
#we do this dynamically because Tcl ensembles (even some core ones) can have subcommands added at runtime.
proc array_subcommands {} {
#dict set groups "" {bogus names} ;#test adding both existant and nonexistant to the default group
dict set groups "search" {startsearch anymore nextelement donesearch}
return [punk::args::ensemble_subcommands_definition -groupdict $groups -columns 2 array]
}
lappend PUNKARGS [list {
@dynamic
@id -id ::array
@cmd -name "Built-in: array"\
-summary\
"Manipulate array variables"\
-help\
"This command performs one of several operations on the variable given by
arrayName. Unless otherwise specified for individual commands below,
arrayName must be the name of an existing array variable. The subcommand
argument determines what action is carried out by the command."
@leaders
${[punk::args::moduledoc::tclcore::argdoc::array_subcommands]}
@values -unnamed true
} "@doc -name Manpage: -url [manpage_tcl array]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::tcl::array::default
@cmd -name "Built-in: array default"\
-summary\
"Manages the default value of the array."\
-help\
"Arrays initially have no default value, but this command allows you to set one;
the default value will be returned when reading from an element of the array
${$I}arrayName${$NI} if the read would otherwise result in an error.
Note that this may cause the ${$B}append${$N}, ${$B}dict${$N}, ${$B}incr${$N} and ${$B}lappend${$N}
commands to change their behaviour in relation to non-existing array elements."
@form -form exists
@leaders
exists -type literal(exists) -help\
"This returns a boolean value indicating whether a default value has
been set for the array ${$I}arrayName${$NI}. Returns a false value if
${$I}arrayName${$NI} does not exist. Raises an error if ${$I}arrayName${$NI}
is an existing variable that is not an array."
@values -min 1 -max 1
arrayName
@form -form get
@leaders
get -type literal(get) -help\
"This returns the current default value for the array ${$I}arrayName${$NI}.
Raises an error if ${$I}arrayName${$NI} is an existing variable that is
not an array, or if ${$I}arrayName${$NI} is an array without a default value."
@values -min 1 -max 1
arrayName
@form -form set
@leaders
set -type literal(set) -help\
"This sets the default value for the array ${$I}arrayName${$NI} to ${$I}value${$NI}.
Returns the empty string. Raises an error if ${$I}arrayName${$NI} is an existing
variable that is not an array, or if ${$I}arrayName${$NI} is an illegal name for an
array. If ${$I}arrayName${$NI} does not currently exist, it is created as an empty
array as well as having its default value set."
@values -min 2 -max 2
arrayName
value
@form -form unset
@leaders
unset -type literal(unset) -help\
"This removes the default value for the array ${$I}arrayName${$NI} and returns
the empty string. Does nothing if ${$I}arrayName${$NI} does not have a default
value. Raises an error if ${$I}arrayName${$NI} is an existing variable that is
not an array."
@values -min 1 -max 1
arrayName
} "@doc -name Manpage: -url [manpage_tcl array]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
}
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
namespace eval argdoc {
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::break
@cmd -name "Built-in: break"\
-summary\
"Abort looping command"\
-help\
"This command is typically invoked inside the body of a looping command such
as ${$B}for${$N} or ${$B}foreach${$N} or ${$B}while${$N}. It returns a
3 (${$B}TCL_BREAK${$N}) result code, which causes a break exception
to occur. The exception causes the current script to be aborted out to the
innermost containing loop command, which then aborts its execution and
returns normally. Break exceptions are also handled in a few other
situations, such as the ${$B}catch${$N} command, Tk event bindings, and
the outermost scripts of procedure bodies."
@values -min 0 -max 0
} "@doc -name Manpage: -url [manpage_tcl break]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::catch
@cmd -name "Built-in: catch"\
-summary\
"Evaluate script and trap exceptional returns."\
-help\
"The catch command may be used to prevent errors from aborting command
interpretation. The catch command calls the Tcl interpreter recursively to
execute script, and always returns without raising an error, regardless of
any errors that might occur while executing script.
If script raises an error, catch will return a non-zero integer value
corresponding to the exceptional return code returned by evaluation of
script. Tcl defines the normal return code from script evaluation to be
zero (0), or TCL_OK. Tcl also defines four exceptional return codes:
1 (TCL_ERROR), 2 (TCL_RETURN), 3 (TCL_BREAK), and 4 (TCL_CONTINUE).
Errors during evaluation of a script are indicated by a return code of
TCL_ERROR. The other exceptional return codes are returned by the return,
break, and continue commands and in other special situations as documented.
New commands defined by Tcl packages as well as scripts that make use of the
return -code command can return other integer values as the return code.
These must however lie outside the range reserved for Tcl as documented for
the return command.
If the resultVarName argument is given, then the variable it names is set to
the result of the script evaluation. When the return code from the script is
1 (TCL_ERROR), the value stored in resultVarName is an error message. When
the return code from the script is 0 (TCL_OK), the value stored in
resultVarName is the value returned from script.
If the optionsVarName argument is given, then the variable it names is set to
a dictionary of return options returned by evaluation of script. Tcl specifies
two entries that are always defined in the dictionary: -code and -level. When
the return code from evaluation of script is not TCL_RETURN, the value of the
-level entry will be 0, and the value of the -code entry will be the same as
the return code. Only when the return code is TCL_RETURN will the values of
the -level and -code entries be something else, as further described in the
documentation for the return command.
When the return code from evaluation of script is TCL_ERROR, four additional
entries are defined in the dictionary of return options stored in optionsVarName:
-errorinfo, -errorcode, -errorline, and -errorstack. The value of the -errorinfo
entry is a formatted stack trace containing more information about the context in
which the error happened. The formatted stack trace is meant to be read by a
person. The value of the -errorcode entry is additional information about the
error stored as a list. The -errorcode value is meant to be further processed by
programs, and may not be particularly readable by people. The value of the
-errorline entry is an integer indicating which line of script was being
evaluated when the error occurred. The value of the -errorstack entry is an
even-sized list made of token-parameter pairs accumulated while unwinding the
stack. The token may be CALL, in which case the parameter is a list made of the
proc name and arguments at the corresponding level; or it may be UP, in which
case the parameter is the relative level (as in uplevel) of the previous CALL.
The salient differences with respect to -errorinfo are that:
1. it is a machine-readable form that is amenable to processing with
[foreach {tok prm} ...],
2. it contains the true (substituted) values passed to the functions, instead of
the static text of the calling sites, and
3. it is coarser-grained, with only one element per stack frame (like procs;
no separate elements for foreach constructs for example).
The values of the -errorinfo and -errorcode entries of the most recent error are
also available as values of the global variables ::errorInfo and ::errorCode
respectively. The value of the -errorstack entry surfaces as info errorstack.
Tcl packages may provide commands that set other entries in the dictionary of
return options, and the return command may be used by scripts to set return options
in addition to those defined above."
@values -min 1 -max 3
script
resultVarName -type string -optional 1
optionsVarName -type string -optional 1
} "@doc -name Manpage: -url [manpage_tcl catch]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
#TODO - add CLOCK_ARITHMETIC documentation
#TODO - TIME ZONES documentation?
lappend PUNKARGS [list {
@id -id ::tcl::clock::add
@cmd -name "Built-in: tcl::clock::add"\
-summary\
"Add an offset to timeVal in seconds (base 1970-01-01 00:00 UTC)"\
-help\
"Adds a (possibly negative) offset to a time that is expressed as an integer number of seconds. See CLOCK ARITHMETIC for a full description."
@leaders -min 1 -max -1
timeVal -type integer|literal(now) -help\
"Time value in integer number of seconds since epoch time.
Instead of timeVal a non-integer value now can be used as replacement for today,
which is simply interpolated to the run-time as value of clock seconds."
count_unit -type {int string} -multiple 1 -optional 1 -help\
"unit is one of seconds,minutes,hours,cays,weekdays,weeks,months or years"
@opts
-timezone -type string -choicerestricted 0 -choiceprefix 0 -choicecolumns 7\
-help\
"e.g (from tzdata file)
:localtime
:UTC
:Australia/Sydney
:America/New_York
Note that the choices listed below are case insensitive, but the location based timezones
beginning with a colon are case sensitive.
See 'TIME ZONES' in the clock manpage"\
-choices {
gmt ut utc bst wet wat at
nft nst ndt ast adt est edt
cst cdt mst mdt pst pdt yst
ydt hst hdt cat ahst nt idlw
cet cest met mewt mest swt sst
eet eest bt it zp4 zp5 ist
zp6 wast wadt jt cct jst cast
cadt east eadt gst nzt nzst nzdt
idle
}
-locale -type string -help\
"Specifies that locale-dependent scanning and formatting (and date arithmetic for dates preceding
the adoption of the Gregorian calendar) is to be done in the locale identified by localeName.
The locale name may be any of the locales acceptable to the msgcat package, or it may be the special
name system, which represents the current locale of the process, or the null string, which
represents Tcl's default locale.
e.g en_US"
-gmt -type boolean -help\
"If boolean is true, specifies that a time specified to clock add, clock format or clock scan should be processed in UTC.
If boolean is false, the processing defaults to the local time zone. This usage is obsolete; the correct current usage
is to specify the UTC time zone with -timezone :UTC or any of the equivalent ways to specify it."
@values -min 0 -max 0
} "@doc -name Manpage: -url [manpage_tcl clock]" ]
lappend PUNKARGS [list {
@id -id ::tcl::clock::format
@cmd -name "Built-in: tcl::clock::format"\
-summary\
"Format a time that is expressed as an integer number of seconds."\
-help\
"Formats a time that is expressed as an integer number of seconds into a format intended
for consumption by users or external programs. See ${$B}CLOCK ARITHMETIC${$N} for a full description."
@leaders -min 1 -max -1
timeVal -type integer|literal(now) -help\
"Time value in integer number of seconds since epoch time.
Instead of timeVal a non-integer value now can be used as replacement for today,
which is simply interpolated to the run-time as value of clock seconds."
@opts
${[punk::args::resolved_def -types opts ::tcl::clock::add -*]}
-format -type string -help\
"A string that specifies how the date and time are to be formatted.
The string consists of any number of characters other than the per-cent sign (%)
interspersed with any number of format groups, which are two-character sequences
beginning with the per-cent sign. The permissible format groups, and their
interpretation, are described under ${$B}FORMAT GROUPS${$N}."
@values -min 0 -max 0
} "@doc -name Manpage: -url [manpage_tcl clock]" ]
#::tcl::clock::clicks
#::tcl::clock::format
#review - definition doesn't preclude supplying both -milliseconds and -microseconds, but they are mutually exclusive
#lappend PUNKARGS [list {
# @id -id ::tcl::clock::clicks
# @cmd -name "Built-in: tcl::clock::clicks"\
# -summary\
# "high-resolution time value as system-dependent integer."\
# -help\
# "If no -option argument is supplied, returns a high-resolution time value as a system-dependent integer value.
# The unit of the value is system-dependent but should be the highest resolution clock available on the system
# such as a CPU cycle counter. See ${$B}HIGH RESOLUTION TIMERS${$N} for a full description."
# @opts
# -milliseconds -type none -help\
# "Synonymous with ${$B}clock milliseconds${$N}.
# This usage is obsolete, and ${$B}clock milliseconds${$N} is to be
# considered the preferred way of obtaining a count of milliseconds."
# -microseconds -type none -help\
# "Synonymous with ${$B}clock microseconds${$N}.
# This usage is obsolete, and ${$B}clock microseconds${$N} is to be
# considered the preferred way of obtaining a count of microseconds."
# @values -min 0 -max 0
#} "@doc -name Manpage: -url [manpage_tcl clock]" ]
lappend PUNKARGS [list {
@id -id ::tcl::clock::clicks
@cmd -name "Built-in: tcl::clock::clicks"\
-summary\
"high-resolution time value as system-dependent integer."\
-help\
"If no option argument is supplied, returns a high-resolution time value as a system-dependent integer value.
The unit of the value is system-dependent but should be the highest resolution clock available on the system
such as a CPU cycle counter. See ${$B}HIGH RESOLUTION TIMERS${$N} for a full description."
@values -min 0 -max 1
option -optional 1 -type {literalprefix(-milliseconds)|literalprefix(-microseconds)} -choices {-milliseconds -microseconds}\
-choicelabels {
-milliseconds
"Synonymous with ${$B}clock milliseconds${$N}.
This usage is obsolete, and ${$B}clock milliseconds${$N} is to be
considered the preferred way of obtaining a count of milliseconds."
-microseconds
"Synonymous with ${$B}clock microseconds${$N}.
This usage is obsolete, and ${$B}clock microseconds${$N} is to be
considered the preferred way of obtaining a count of microseconds."
}\
-choicecolumns 1
} "@doc -name Manpage: -url [manpage_tcl clock]" ]
lappend PUNKARGS [list {
@id -id ::tcl::clock::microseconds
@cmd -name "Built-in: tcl::clock::microseconds"\
-summary\
"Current time as an integer number of microseconds."\
-help\
"Returns the current time as an integer number of microseconds. See ${$B}HIGH RESOLUTION TIMERS${$N} for a full description."
@values -min 0 -max 0
} "@doc -name Manpage: -url [manpage_tcl clock]" ]
lappend PUNKARGS [list {
@id -id ::tcl::clock::milliseconds
@cmd -name "Built-in: tcl::clock::milliseconds"\
-summary\
"Current time as an integer number of milliseconds."\
-help\
"Returns the current time as an integer number of milliseconds. See ${$B}HIGH RESOLUTION TIMERS${$N} for a full description."
@values -min 0 -max 0
} "@doc -name Manpage: -url [manpage_tcl clock]" ]
lappend PUNKARGS [list {
@id -id ::tcl::clock::seconds
@cmd -name "Built-in: tcl::clock::seconds"\
-summary\
"Current time as an integer number of seconds."\
-help\
"Returns the current time as an integer number of seconds."
@values -min 0 -max 0
} "@doc -name Manpage: -url [manpage_tcl clock]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@dynamic
@id -id ::concat
@cmd -name "Built-in: concat"\
-summary\
"Join lists together."\
-help\
"This command joins each of its arguments together with spaces after trimming
leading and trailing white-space from each of them. If all of the arguments
are lists, this has the same effect as concatenating them into a single list.
Arguments that are empty (after trimming) are ignored entirely. It permits
any number of arguments; if no args are supplied, the result is an empty
string."
@values -min 0
arg -type string -optional 1 -multiple 1 -help\
"Usually, but not necessarily a proper Tcl list"
} "@doc -name Manpage: -url [manpage_tcl concat]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::const
@cmd -name "Built-in: const"\
-summary\
"Create and initialise a constant."\
-help\
"This command is normally used within a procedure body (or method body,
or lambda term) to create a constant within that procedure, or within a
namespace eval body to create a constant within that namespace. The
constant is an unmodifiable variable, called varName, that is initialised
with value. The result of const is always the empty string on success.
If a variable varname does not exist, it is create with its value set to
value and marked as a constant; this means that no other command (e.g set,
append, incr, unset) may modify or remove the variable; variables are
checked for whether they are constants before any traces are called. If a
variable varName already exists, it is an error unless that variable is
marked as a constant (in which case const is a no-op)
The varName may not be a qualified name or reference an element of an
array by any means. If the variable exists and is an array, that is an
error. Constants are normally only removed by their containing procedure
exiting or their namespace being deleted.
"
@values -min 1 -max 2
varName -help ""
value
} "@doc -name Manpage: -url [manpage_tcl const]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::continue
@cmd -name "Built-in: continue"\
-summary\
"Skip to the next iteration of a loop."\
-help\
"This command is typically invoked inside the body of a looping command such
as ${$B}for${$N} or ${$B}foreach${$N} or ${$B}while${$N}. It returns a
4 (${$B}TCL_CONTINUE${$N}) result code, which causes a continue exception
to occur. The exception causes the current script to be aborted out to the
innermost containing loop command, which then continues with the next
iteration of the loop. Continue exceptions are also handled in a few other
situations, such as the ${$B}catch${$N} command and the outermost scripts of
procedure bodies."
@values -min 0 -max 0
} "@doc -name Manpage: -url [manpage_tcl continue]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::eof
@cmd -name "Built-in: eof"\
-summary\
"Check for end of file condition on channel"\
-help\
"Test whether the last input operation on the channel called ${$I}channel${$NI}
failed because the end of the data stream was reached, returning 1 if end-of-file
was reached, and 0 otherwise.
The ${$B}eof${$N} command has been superceded by the ${$B}chan eof${$N} command
which supports the same syntax and options."
@values -min 1 -max 1
channel -help \
""
} "@doc -name Manpage: -url [manpage_tcl eof]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::error
@cmd -name "Built-in: error"\
-summary\
"Generate an error."\
-help\
"Returns a TCL_ERROR code, which causes command interpretation to be unwound.
Message is a string that is returned to the application to indicate what went
wrong.
The -errorinfo return option of an interpreter is used to accumulate a stack
trace of what was in progress when an error occurred; as nested commands
unwind, the Tcl interpreter adds information to the -errorinfo return option.
If the info argument is present, it is used to initialize the -errorinfo
return options and the first increment of unwind information will not be added
by the Tcl interpreter. In other words, the command containing the error
command will not appear in the stack trace; in its place will be info.
Historically, this feature had been most useful in conjunction with the catch
command: if a caught error cannot be handled successfully, info can be used to
return a stack trace reflecting the original point of occurrence of the error:
${[punk::args::moduledoc::tclcore::argdoc::example {
catch {...} errMsg
set savedInfo $::errorInfo
...
error $errMsg $savedInfo
}]}
When working with Tcl 8.5 or later, the following code should be used intead:
${[punk::args::moduledoc::tclcore::argdoc::example {
catch {...} errMsg options
...
return -options $options $errMsg
}]}
If the code argument is present, then its value is stored in the -errorcode
return option. The -errorcode return option is intended to hold a
machine-readable description of the error in cases where such information is
available; see the return manual page for information on the proper format for
this option's value."
@values -min 1 -max 3
message -type string
info -type string -optional 1
code -type list -optional 1 -help\
"machine-readable data to store in -errorcode return option"
} "@doc -name Manpage: -url [manpage_tcl error]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::eval
@cmd -name "Built-in: eval"\
-summary\
"Evaluate a Tcl script."\
-help\
"${$B}Eval${$N} takes one or more arguments, which together comprise a Tcl script containing
one or more commands. ${$B}Eval${$N} concatenates all its arguments in the same fashion as the
${$B}concat${$N} command, passes the concatenated string to the Tcl interpreter recursively,
and returns the result of that evaluation (or any error generated by it).
Note that the ${$B}list${$N} command quotes sequences of words in such a way that they are not
further expanded by the ${$B}eval${$N} command; for any values, $a, $b, and $c, these two lines
are effectively equivalent:
eval [list $a $b $c]
$a $b $c
"
@values -min 1 -max -1
arg -multiple 1
} "@doc -name Manpage: -url [manpage_tcl eval]"\
{@examples -help {
Often, it is useful to store a fragment of a script in a variable and execute it later on
with extra values appended. This technique is used in a number of places throughout the Tcl
core (e.g. in ${$B}fcopy${$N}, ${$B}lsort${$N} and ${$B}trace${$N} command callbacks). This example shows how to do this
using core Tcl commands:
${[punk::args::moduledoc::tclcore::argdoc::example {
set script {
puts "logging now"
lappend $myCurrentLogVar
}
set myCurrentLogVar log1
# Set up a switch of logging variable part way through!
after 20000 set myCurrentLogVar log2
for {set i 0} {$i<10} {incr i} {
# Introduce a random delay
after [expr {int(5000 * rand())}]
update ;# Check for the asynch log switch
eval $script $i [clock clicks]
}
}]}
Note that in the most common case (where the script fragment is actually just a list of words
forming a command prefix), it is better to use {*}$script when doing this sort of invocation
pattern. It is less general than the eval command, and hence easier to make robust in practice.
The following procedure acts in a way that is analogous to the lappend command, except it
inserts the argument values at the start of the list in the variable:
${[punk::args::moduledoc::tclcore::argdoc::example {
proc lprepend {varName args} {
upvar 1 $varName var
# Ensure that the variable exists and contains a list
lappend var
# Now we insert all the arguments in one go
set var [eval [list linsert $var 0] $args]
}
}]}
However, the last line would now normally be written without eval, like this:
${[punk::args::moduledoc::tclcore::argdoc::example {
set var [linsert $var 0 {*}$args]
}]}
Or indeed like this:
${[punk::args::moduledoc::tclcore::argdoc::example {
set var [list {*}$args {*}$var]
}]}
}
}]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::exit
@cmd -name "Built-in: exit"\
-summary\
"End the application."\
-help\
"Terminate the process, returning ${$I}returnCode${$NI} to the system as the exit status.
If ${$I}returnCode${$NI} is not specified then it default to 0."
@values -min 0 -max 1
returnCode -type integer -default 0 -optional 1
} "@doc -name Manpage: -url [manpage_tcl exit]"\
{@examples -help {
Since non-zero exit codes are usually interpreted as error cases by the calling process,
the exit command is an important part of signaling that something fatal has gone wrong.
This code fragment is useful in scripts to act as a general problem trap:
${[punk::args::moduledoc::tclcore::argdoc::example {
proc main {} {
# ... put the real main code in here ...
}
if {[catch {main} msg options]} {
puts stderr "unexpected script error: $msg"
if {[info exists env(DEBUG)]} {
puts stderr "---- BEGIN TRACE ----"
puts stderr [dict get $options -errorinfo]
puts stderr "---- END TRACE ----"
}
# Reserve code 1 for "expected" error exits...
exit 2
}
}]}
}
}]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::tcl::build-info
@cmd -name "Built-in: tcl::build-info"\
-summary\
"Build info."\
-help\
"This command provides a way to retrieve information about how Tcl was built.
Without any options, the command returns the Tcl patchlevel, followed by the
'+'-sign, followed by the fossil commit-id followed by a list of dot-separated
tags. If a field is given, this command extracts that field as described below.
Any other field value not mentioned below will always return \"0\"."
@leaders -min 0 -max 1
field -type string -optional 1 -choicecolumns 3\
-choices {
clang commit compiledebug compiler compilestats cplusplus debug gcc icc ilp32 memdebug msvc
nmake no-deprecate no-thread no-optimize objective-c objective-cplusplus patchlevel profile
purify static tommath version zlib
}\
-choicelabels {
clang\
" Returns the clang version number (as 4 digits)
if Tcl is compiled with clang, 0 otherwise."
commit\
" Returns the fossil commit-id where Tcl was
built from."
compiledebug\
" Returns 1 if Tcl is compiled with
${$B}-DTCL_COMPILE_DEBUG${$N}, 0 otherwise."
compiler\
" Returns the compiler name (either clang, gcc,
icc or msvc), followed by a dash and a (4-digit)
version number."
compilestats\
" Returns 1 if Tcl is compiled with
${$B}-DTCL_COMPILE_STATS${$N}, 0 otherwise."
cplusplus\
" Returns 1 if Tcl is compiled with a C++
compiler, 0 otherwise."
debug\
" Returns 1 if Tcl is not compiled with
${$B}-DNDEBUG${$N}, 0 otherwise."
gcc\
" Returns the gcc version number (as 4 digits)
if Tcl is compiled with gcc, 0 otherwise."
icc\
" Returns the icc version number (as 4 digits)
if Tcl is compiled with icc, 0 otherwise."
ilp32\
" Returns 1 if Tcl is compiled such that integers,
longs and pointers are all 32-bit, 0 otherwise."
memdebug\
" Returns 1 if Tcl is compiled with
${$B}-DTCL_MEM_DEBUG${$N}, 0 otherwise."
msvc\
" Returns the msvc version number (as 4 digits)
if Tcl is compiled with msvc, 0 otherwise."
nmake\
" Returns 1 if Tcl is built using nmake,
0 otherwise"
no-deprecate\
" Returns 1 if Tcl is compiled with
${$B}-DTCL_NO_DEPRECATED${$N}, 0 otherwise."
no-thread\
" Returns 1 if Tcl is compiled with
${$B}-DTCL_THREADS${$N}=0, 0 otherwise."
no-optimize\
" Returns 1 if Tcl is not compiled with
${$B}-DTCL_CFG_OPTIMIZED${$N}, 0 otherwise."
objective-c\
" Returns 1 if Tcl is compiled with an
objective-c compiler, 0 otherwise."
objective-cplusplus\
" Returns 1 if Tcl is compiled with an
objective-c++ compiler, 0 otherwise."
patchlevel\
" Returns the Tcl patchlevel, same as
${$B}info patchlevel${$N}."
profile\
" Returns 1 if Tcl is compiled with
${$B}-DTCL_CFG_PROFILED${$N}, 0 otherwise."
purify\
" Returns 1 if Tcl is compiled with
${$B}-DPURIFY${$N}, 0 otherwise."
static\
" Returns 1 if Tcl is compiled as a static
library, 0 otherwise."
tommath\
" Returns the libtommath version number
(as 4 digits) if libtommath is built into
Tcl, 0 otherwise."
version\
" Returns the Tcl version, same as
${$B}info tclversion${$N}."
zlib\
" Returns the zlib version number (as 4 digits)
if zlib is built into Tcl, 0 otherwise."
}
@values -min 0 -max 0
} "@doc -name Manpage: -url [manpage_tcl buildinfo]"\
{@examples -help {
These show the use of ::tcl::build-info.
${[punk::args::moduledoc::tclcore::argdoc::example {
::tcl::build-info
9.0.2+af16c07b81655fabde8028374161ad54b84ef9956843c63f49976b4ef601b611.gcc-1204
::tcl::build-info commit
af16c07b81655fabde8028374161ad54b84ef9956843c63f49976b4ef601b611
::tcl::build-info compiler
gcc-1204
::tcl::build-info gcc
1204
::tcl::build-info version
9.0
::tcl::build-info patchlevel
9.0.2
}]}
}
}]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::exec
@cmd -name "Built-in: exec"\
-summary\
"Invoke subprocesses."\
-help\
"This command treats its arguments as the specification of one or more
subprocesses to execute. The arguments take the form of a standard shell
pipeline where each arg becomes one word of a command, and each distinct
command becomes a subprocess. The result of the command is the standard
output of the final subprocess in the pipeline, interpreted using the
system encoding; to use any other encoding (especially including binary
data), the pipeline must be opened, configured and read explicitly.
If the initial arguments to exec start with - then they are treated as
command-line switches and are not part of the pipeline specification.
(see manpage for full details - especially 'portability issues')"
@leaders -min 0 -max 0
@opts
-ignorestderr -type none -help\
"stops the ${$B}exec${$N} command from treating the output
of messages to the pipeline's standard error channel as an
error case."
-keepnewline -type none -help\
"Retains a trailing newline in the pipeline's output.
Normally a trailing newline will be deleted."
-- -type none -help\
"Marks the end of switches. The argument following this
one will be treated as the first ${$I}arg${$NI} even if it
starts with a -."
@values -min 1 -max -1
arg -type string\
-help "Command and arguments to be executed. May be interspersed with
various 'control of flow' operators which are not passed to the subprocess."\
-multiple 1 -optional 0 -choicerestricted 0 -choices {"|" "|&" ">>" "2>>" ">>&"}
#we must give an optional value a -default - or it will be processed as empty string and won't validate if not received!
#(default values are never validated)
stderr_to_result -type {literal(2>@1)} -optional 1 -default 0
bgexec -type {literal(&)} -optional 1 -default 0
} "@doc -name Manpage: -url [manpage_tcl expr]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::expr
@cmd -name "Built-in: expr"\
-summary\
"Evaluate an expression."\
-help\
"Concatenates ${$I}args${$NI}, separated by a space, into an expression,
and evaluates that expression, returning its value. The operators permitted
in an expression include a subset of the operators permitted in C expressions.
For those operators common to both Tcl and C, Tcl applies the same meaning and
precedence as the corresponding C operators. The value of an expression is
often a numeric result, either an integer or a floating-point value, but may
also be a non-numeric value. For example, the expression
${$B}expr${$N} 8.2 + 6
evaluates to 14.2. Expressions differ from C expressions in the way that
operands are specified. Expressions also support non-numeric operands, string
comparisons, and some additional operators not found in C.
When the result of expression is an integer, it is in decimal form, and when
the result is a floating-point number, it is in the form produced by the
${$B}%g${$N} format specifier of ${$B}format${$N}.
At any point in the expression except within double quotes or braces, ${$B}#${$N}
is the beginning of a comment, which lasts to the end of the line or end of
the expression, whichever comes first.
(see manpage for full details)"
@values -min 1 -max -1
arg -type string -multiple 1 -optional 0
} "@doc -name Manpage: -url [manpage_tcl expr]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::for
@cmd -name "Built-in: for"\
-summary\
"'For' loop"\
-help\
"${$B}For${$N} is a looping command, simliar in structure to the C ${$B}for${$N}
statement. The ${$I}start${$NI}, ${$I}next${$NI}, and ${$I}body${$NI} arguments
must be Tcl command strings, and ${$I}test${$NI} is an expression string. The
${$B}for${$N} command first invokes the Tcl interpreter to execute ${$I}start${$NI}.
Then it repeatedly evaluates ${$I}test${$NI} as an expression; if the result
is non-zero it invokes the Tcl interpreter on ${$I}body${$NI}, then invokes
the Tcl interpreter on ${$I}next${$NI}, then repeats the loop. The command
terminates when ${$I}test${$NI} evaluates to 0. If a ${$B}continue${$N} command
is invoked within ${$I}body${$NI} then any remaining commands in the current
execution of ${$I}body${$NI} are skipped; processing continues by invoking the
Tcl interpreter on ${$I}next${$NI}, then evaluating ${$I}test${$NI}, and so on.
If a ${$B}break${$N} command is invoked within ${I}body${$NI} or ${$I}next${$NI},
then the ${$B}for${$N} command will return immediately. The operation of ${$B}break${$N}
and ${$B}continue${$N} are similar to corresponding statements in C.
${$B}for${$N} returns an empty string.
Note that ${$I}test${$NI} should almost always be enclosed in braces. If not,
variable substitutions will be made before the ${$B}for${$N} command starts
executing, which means that variable changes made by the loop body will not
be considered in the expression. This is likely to result in an infinite loop.
If ${$I}test${$NI} is enclosed in braces, variable substitutions are delayed
until the expression is evaluated (before each loop iteration), so changes
in the variables will be visible.
"
@values -min 4 -max 4
start -type script
test -type expr
next -type script
body -type script -help\
"Tcl script"
} "@doc -name Manpage: -url [manpage_tcl for]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::foreach
@cmd -name "Built-in: foreach"\
-summary\
"Iterate over all elements in one or more lists."\
-help\
"The ${$B}foreach${$N} command implements a loop where the loop variable(s)
take on values from one or more lists. In the simplest case there is one loop
variable, ${$I}varname${$NI} and one list, ${$I}list${$NI}, that is a list of values
to assign to ${$I}varname${$NI}. The body argument is a Tcl script. For each element
of ${$I}list${$NI} (in order from first to last), ${$B}foreach${$N} assigns the contents
of the element to ${$I}varname${$NI} as if the ${$B}lindex${$N} command had been used
to extract the element, then calls the Tcl interpreter to execute ${$I}body${$NI}.
In the general case there can be more than one value list, and each value list
can be associated with a list of loop variables. During each iteration of the
loop the variable of each ${$I}varlist${$NI} are assigned consecutive values from
the corresponding ${$I}list${$NI}. Values in each ${$I}list${$NI} are used in order from
first to last, and each value is used exactly once. The total number of loop
iterations is large enough to use up all the values from all the value lists.
If a value list does not contain enough elements for each of its loop variables
in each iteration, empty values are used for the missing elements.
The ${$B}break${$N} and ${$B}continue${$N} statements may be invoked inside ${$I}body${$NI},
with the same effect as in the ${$B}for${$N} command.
${$B}Foreach${$N} returns an empty string."
@values
"varlist list" -type {list list} -typesynopsis {varlist list} -multiple 1 -optional 0
body -type string -optional 0 -help\
"Tcl script"
} "@doc -name Manpage: -url [manpage_tcl foreach]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::gets
@cmd -name "Built-in: gets"\
-summary\
"Read a line from a channel"\
-help\
"The ${$B}gets${$N} command has been superceded by the ${$B}chan gets${$N} command
which supports the same syntax and optsion."
@values
channel
varName -optional 1
} "@doc -name Manpage: -url [manpage_tcl gets]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::glob
@cmd -name "Built-in: glob"\
-summary\
"Return names of files that match patterns."\
-help\
"This command performs file name globbing in a fashion similar to the csh shell or bash shell.
It returns a list of the files whose names match any of the pattern arguments. No particular
order is guaranteed in the list, so if a sorted list is required the caller should use lsort."
@opts
-directory -type directory -help\
"Search for files which match the given patterns starting in the given ${$I}directory${$NI}.
This allows searching of directories whose name contains glob-sensitive characters
without the need to quote such characters explicitly. This option may not be used
in conjunction with ${$B}-path${$N}, which is used to allow searching for complete file
paths whose names may contain glob-sensitive characters."
-join -type none -help\
"The remaining pattern arguments, after option processing, are treated as a single
pattern obtained by joining the arguments with directory separators."
-nocomplain -type none -help\
"Allows an empty list to be returned without error; This is the default behavior in Tcl 9.0,
so this switch has no effect any more."
-path -type string -help\
"Search for files with the given pathPrefix where the rest of the name matches the given
patterns. This allows searching for files with names similar to a given file (as opposed
to a directory) even when the names contain glob-sensitive characters. This option may not
be used in conjunction with ${$B}-directory${$N}. For example, to find all files with the same root
name as $path, but differing extensions, you should use
${$B}glob -path [file rootname $path] .*${$N} which will work even if $path contains numerous
glob-sensitive characters."
-tails -type none -help\
"Only return the part of each file found which follows the last directory named in any ${$B}-directory${$N}
or ${$B}-path${$N} path specification. Thus ${$B}glob -tails -directory $dir *${$N} is equivalent to
${$B}set pwd [pwd]; cd $dir; glob *; cd $pwd${$N}. For -path specifications, the returned names will
include the last path segment, so ${$B}glob -tails -path [file rootname /home/fred/foo.tex] .*${$N} will
return paths like foo.aux foo.bib foo.tex etc."
-types -type list -help\
"Only list files or directories which match typeList, where the items in the list have two forms. The
first form is like the -type option of the Unix find command: b (block special file),
c (character special file), d (directory), f (plain file), l (symbolic link), p (named pipe), or
s (socket), where multiple types may be specified in the list. Glob will return all files which match
at least one of the types given. Note that symbolic links will be returned both if -types l is given,
or if the target of a link matches the requested type. So, a link to a directory will be returned
if -types d was specified.
The second form specifies types where all the types given must match. These are r, w, x as file
permissions, and readonly, hidden as special permission cases. On the Macintosh, macOS types and
creators are also supported, where any item which is four characters long is assumed to be a macOS
type (e.g. TEXT). Items which are of the form {macintosh type XXXX} or {macintosh creator XXXX} will
match types or creators respectively. Unrecognized types, or specifications of multiple macOS
types/creators will signal an error.
The two forms may be mixed, so -types {d f r w} will find all regular files OR directories that have
both read AND write permissions. The following are equivalent:
${[punk::args::moduledoc::tclcore::argdoc::example {
glob -type d *
glob */}
]}
except that the first case doesn't return the trailing / and is more platform independent."
-- -type none -help\
"Marks the end of switches. The argument following this one will be treated as a pattern even if it
starts with a -."
@values -min 1 -max -1
pattern -type string -multiple 1 -optional 1 -help\
"The pattern arguments may contain any of the following special characters, which are a superset of
those supported by string match:
${$B}?${$N}
Matches any single character.
${$B}*${$N}
Matches any sequence of zero or more characters.
${$B}[chars]${$N}
Matches any single character in ${$I}chars${$NI}. If ${$I}chars${$NI} contains a sequence of
the form a-b then any character between ${$I}a${$NI} and ${$I}b${$NI} (inclusive) will match.
${$B}\x${$N}
Matches the character ${$I}x${$NI}
${$B}{a,b,...}${$N}
Matches any of the sub-patterns ${$I}a${$NI}, ${$I}b${$NI}, etc.
On Unix, as with csh, a . at the beginning of a file's name or just after a / must be matched
explicitly or with a {} construct, unless the -types hidden flag is given (since . at the
beginning of a file's name indicates that it is hidden). On other platforms, files beginning with
a . are handled no differently to any others, except the special directories . and ..
which must be matched explicitly (this is to avoid a recursive pattern like glob -join * * * *
from recursing up the directory hierarchy as well as down). In addition, all / characters must be
matched explicitly.
The ${$B}glob${$N} command differs from csh globbing in two ways. First, it does not sort its result list
(use the lsort command if you want the list sorted). Second, glob only returns the names of files
that actually exist; in csh no check for existence is made unless a pattern contains a ?, *,
or [] construct."
} "@doc -name Manpage: -url [manpage_tcl glob]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::global
@cmd -name "Built-in: global"\
-summary\
"Access global variables from procs."\
-help\
"This command has no effect unless executed in the context of a proc body. If the ${$B}global${$N} command is executed
in the context of a proc body, it creates local variables linked to the corresponding global variables (though
these linked variables, like those created by ${$B}upvar${$N}, are not included in the list returned by ${$B}info locals${$N}).
If ${$I}varname${$NI} contains namespace qualifiers, the local variable's name is the unqualified name of the global
variable, as determined by the ${$B}namespace tail${$N} command.
${$I}varname${$NI} is always treated as the name of a variable, not an array element. An error is returned if the name
looks like an array element, such as ${$B}a(b)${$N}."
@values -min 0 -max -1
varName -multiple 1 -optional 1
} "@doc -name Manpage: -url [manpage_tcl global]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
}
############################################################################################################################################################
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# COMMANDS I-L
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
############################################################################################################################################################
namespace eval argdoc {
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::if
@cmd -name "Built-in: if"\
-summary\
"Execute scripts conditionally."\
-help\
"The ${$B}if${$N} command evaluates ${$I}expr1${$NI} as an expression (in the
same way that ${$B}expr${$N} evaluates its argument). The value of the
expression must be a boolean (a numeric value, where 0 is false and anything
is true, or a string value such as ${$B}true${$N} or ${$B}yes${$N} for true
and ${$B}false${$N} or ${$B}no${$N} for false); if it is true then ${$I}body1${$NI}
is executed by passing it to the Tcl interpreter. Otherwise the ${$I}expr${$NI}
from any following ${$I}elseif${$NI} clause is evaluated as an expression and if
it is true then it's ${$I}body${$NI} is evaluated, and so on for each ${$I}elseif${$NI}
clause. If none of the expressions evaluates to true then the ${$I}body${$NI} from the
trailing ${$I}else${$NI} clause is evaluated if present.
The ${$B}then${$N} and ${$B}else${$N} arguments are optional \"noise words\" to make
the command easier to read. There may be any number of ${$B}elseif${$N} clauses,
including zero.
The return value from the command is the result of the body script that was
executed, or an empty string if none of the expressions was non-zero and there was
no trailing ${$I}else${$NI} clause.
(todo: punk::args variable clause length parsing due to 'noise words' - work in progress)"
@leaders -min 0 -max 0
@values -min 2 -max -1
expr1 -type expr -optional 0
then -type literal(then) -optional 1
body1 -type script -optional 0
#todo - punk::args variable-length striding by use of ?name? in -type list
"elseif_clause" -type {literal(elseif) expr ?literal(then)? script} -optional 1 -multiple 1
"else_clause" -type {?literal(else)? script} -optional 1 -multiple 0
} "@doc -name Manpage: -url [manpage_tcl if]"]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::incr
@cmd -name "Built-in: incr"\
-summary\
"Increment the value of a variable."\
-help\
"Increments the value stored in the variable whose name is ${$I}varName${$NI}. The
value of the variable must be an integer. If ${$I}increment${$NI} is supplied then
its value (which must be an integer) is added to the value of variable
${$I}varName${$NI}; otherwise 1 is added to ${$I}varName${$NI}. The new value is stored as a
decimal string in variable ${$I}varName${$NI} and also returned as result.
Starting with the Tcl 8.5 release, the variable ${$I}varName${$NI} passed to ${$B}incr${$N}
may be unset, and in that case, it will be set to the value ${$I}increment${$NI} or
to the default increment value of ${$B}1${$N}. If ${$I}varName${$NI} indicates an element that
does not exist of an array that has a default value set, the sum of the
default value and the ${$I}increment${$NI} (or 1) will be stored in the array element."
@leaders -min 0 -max 0
@values -min 1 -max 2
varName -type string
increment -type integer -optional 1
} "@doc -name Manpage: -url [manpage_tcl incr]"]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@dynamic
@id -id ::join
@cmd -name "Built-in: join"\
-summary\
"Create a string by joining together list elements."\
-help\
"The ${$I}list${$NI} argument must be a valid Tcl list. This command returns the string
formed by joining all of the elements of ${$I}list${$NI} together with ${$I}joinString${$NI}
separating each adjacent pair of elements. The ${$I}joinString${$NI} argument defaults
to a space character."
@values -min 1
list -type list
joinString -type string -default " " -optional 1
} "@doc -name Manpage: -url [manpage_tcl concat]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::lappend
@cmd -name "Built-in: lappend"\
-summary\
"Append list elements onto a variable."\
-help\
"This command treats the variable given by ${$I}listVar${$NI} as a list and
appends each of the ${$I}value${$NI} arguments to that list as a separate
element, with spaces between elements. If ${$I}listVar${$NI} does not exist,
it is created as a list with elements given by the value arguments. If
${$I}listVar${$NI} indicates an element that does not exist of an array that
has a default value set, a list that is comprised of the default value with
all the ${$I}value${$NI} arguments appended as elements will be stored in the
array element. ${$I}Lappend${$NI} is similar to ${$I}append${$NI} except that the
values are appended as list elements rather than raw text. This command
provides a relatively efficient way to build up large lists. For example,
${$B}\"lappend a $b\"${$N} is much more efficient than
${$B}\"set a [concat $a [list $b]]\"${$N} when ${$B}$a${$N} is long."
@values -min 1 -max -1
listVar -type string -help\
"Existing list variable name"
value -type any -optional 1 -multiple 1
} "@doc -name Manpage: -url [manpage_tcl lappend]"]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::lassign
@cmd -name "Built-in: lassign"\
-summary\
"Assign list elements to variables."\
-help\
"This command treats the value ${$I}list${$NI} as a list and assigns
successive elements from that list to the variables given by the
${$I}varName${$NI} arguments in order. If there are more variable
names than list elements, the remaining variables are set to the
empty string. If there are more list elements than variables, a
list of unassigned elements is returned."
@values -min 1 -max -1
list -type list -help\
"tcl list as a value"
varName -type any -optional 1 -multiple 1
} "@doc -name Manpage: -url [manpage_tcl lassign]"]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::ledit
@cmd -name "Built-in: ledit"\
-summary\
"Replace elements of a list stored in variable."\
-help\
"The command fetches the list value in variable listVar and replaces the
elements in the range given by indices first to last (inclusive) with the
value arguments. The resulting list is then stored back in listVar and
returned as the result of the command.
Arguments first and last are index values specifying the first and last
elements of the range to replace. They are interpreted the same as index
values for the command ${$B}string index${$N}, supporting simple index arithmetic
and indices relative to the end of the list. The index ${$B}0${$N} refers to the
first element of the list, and end refers to the last element of the list.
(Unlike with ${$B}lpop${$N}, ${$B}lset${$N}, and ${$B}lindex${$N}, indices into sublists are not
supported.)
If either first or last is less than zero, it is considered to refer to the
position before the first element of the list. This allows elements to be
prepended.
If either first or last indicates a position greater than the index of the
last element of the list, it is treated as if it is an index one greater
than the last element. This allows elements to be appended.
If last is less than first, then any specified elements will be inserted
into the list before the element specified by first with no elements being
deleted.
The value arguments specify zero or more new elements to be added to the
list in place of those that were deleted. Each value argument will become a
separate element of the list. If no value arguments are specified, the
elements between first and last are simply deleted."
@values -min 3 -max -1
listVar -type string -help\
"Existing list variable name"
first -type indexexpression
last -type indexexpression
value -type any -optional 1 -multiple 1
} "@doc -name Manpage: -url [manpage_tcl ledit]"\
{@examples -help {
Prepend to a list.
${[punk::args::moduledoc::tclcore::argdoc::example {
set lst {c d e f g}
-> c d e f g
ledit lst -1 -1 a b
-> a b c d e f g
}]}
Append to the list.
${[punk::args::moduledoc::tclcore::argdoc::example {
ledit lst end+1 end+1 h i
-> a b c d e f g h i
}]}
Delete the third and fourth elements.
${[punk::args::moduledoc::tclcore::argdoc::example {
ledit lst 2 3
-> a b e f g h i
}]}
Replace two elements with three.
${[punk::args::moduledoc::tclcore::argdoc::example {
ledit lst 2 3 x y z
-> a b x y z g h i
set lst
-> a b x y z g h i
}]}
}
}
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::lindex
@cmd -name "Built-in: lindex"\
-summary\
"Retrieve an element from a list."\
-help\
"When no index is supplied or a single index is supplied as an empty list,
the value of the entire list is simply returned.
If a single index is supplied and is a list of indices - this list is used
as a sequence of nested indices.
The command,
lindex $a 1 2 3
or
lindex $l {1 2 3}
is synonymous with
lindex [lindex [lindex $a 1] 2] 3
When presented with a single index, the lindex command treats list as a Tcl list
and returns the index'th element from it (0 refers to the first element of the
list). In extracting the element, lindex observes the same rules concerning
braces and quotes and backslashes as the Tcl command interpreter; however,
variable substution and command substitution do not occur. If index is negative
or greater than or equal to the number of elements in 'list', then an empty
string is returned. The interpretation of each simple index value is the same
as for the command 'string index', supporting simple index arithmetic and
indices relative to the end of the list.
If additional index arguments are supplied, then each argument is used in turn
to select an element from the previous indexing operation, allowing the script
to select elements from sublists."
@values -min 1 -max -1
list -type list -help\
"tcl list as a value"
index -type indexexpression -multiple 1 -optional 1
} "@doc -name Manpage: -url [manpage_tcl lindex]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::linsert
@cmd -name "Built-in: linsert"\
-summary\
"Insert elements into a list."\
-help\
"This command produces a new list from ${$I}list${$NI} by insertaing all of the
${$I}element${$NI} arguments just before the ${$I}index${$NI}'th element of list.
Each ${$I}element${$NI} argument will become a separate element of the new list.
If ${$I}index${$NI} is less than or equal to zero, then the new elements are
inserted at the beginning of the list, and if ${$I}index${$NI} is greater or equal
to the length of ${$I}list${$NI}, it is as if it was ${$B}end${$N}.
As with ${$B}string index${$N}, the ${$I}index${$NI} value supports both simple index
arithmetic and end-relative indexing.
Subject to the restrictions that indices must refer to locations inside the list and
that the ${$I}elements${$NI} will always be inserted in order, insertions are done so
that when ${$I}index${$NI} is start-relative, the first ${$I}element${$NI} will be at that
index in the resulting list, and when ${$I}index${$NI} is end-relative, the last element will
be at that index in the resulting list."
@values -min 2 -max -1
list -type string -help\
"tcl list as a value"
index -type indexexpression
element -type any -optional 1 -multiple 1
@seealso -commands {list list lappend lassign ledit lindex llength lmap lpop lrange lrepeat lreplace lreverse lsearch lseq lset lsort}
} "@doc -name Manpage: -url [manpage_tcl linsert]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::list
@cmd -name "Built-in: list"\
-summary\
"Create a list."\
-help\
"This command returns a list comprised of all the args, or an empty string
if no args are specified. Braces and backslashes get added as necessary,
so that the lindex command may be used on the result to re-extract the
original arguments, and also so that eval may be used to execute the
resulting list, with arg1 comprising the command's name and the other args
comprising its arguments. List produces slightly different results than
concat: concat removes one level of grouping before forming the list,
while list works directly from the original arguments."
@values -min 0 -max -1
arg -type any -optional 1 -multiple 1
} "@doc -name Manpage: -url [manpage_tcl list]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::llength
@cmd -name "Built-in: llength"\
-summary\
"Count the number of elements in a list."\
-help\
"Treats ${$I}list${$NI} as a list and returns a decimal string giving the
number of elements in it."
@values -min 1 -max 1
list -type list -help\
"tcl list as a value"
} "@doc -name Manpage: -url [manpage_tcl llength]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::lmap
@cmd -name "Built-in: lmap"\
-summary\
"Iterate over all elements in one or more lists and collect results."\
-help\
"The ${$B}lmap${$N} command implements a loop where the loop variable(s)
take on values from one or more lists, and the loop returns a list of results
collected from each iteration.
In the simplest case there is one loop variable, ${$I}varname${$NI} and one ${$I}list${$NI},
that is a list of values to assign to ${$I}varName${$NI}. The ${$I}body${$NI}
argument is a Tcl script. For each element of ${$I}list${$NI} (in order from first
to last), ${$B}lmap${$N} assigns the contents of the element to ${$I}varName${$NI}
as if the ${$B}lindex${$N} command had been used to extract the element, then
calls the Tcl interpreter to execute ${$I}body${$NI}.
If execution of the body completes normally then the result of body is appended
to an accumulator list. ${$B}lmap${$N} returns the accumulator list.
In the general case there can be more than one value list, and each value list
can be associated with a list of loop variables. During each iteration of the
loop the variable of each ${$I}varlist${$NI} are assigned consecutive values from
the corresponding ${$I}list${$NI}. Values in each ${$I}list${$NI} are used in order from
first to last, and each value is used exactly once. The total number of loop
iterations is large enough to use up all the values from all the value lists.
If a value list does not contain enough elements for each of its loop variables
in each iteration, empty values are used for the missing elements.
The ${$B}break${$N} and ${$B}continue${$N} statements may be invoked inside ${$I}body${$NI},
with the same effect as in the ${$B}for${$N} and ${$B}foreach${$N} commands.
In these cases the body does not complete normally and the result is not appended
to the accumulator list."
@values
"varlist list" -type {list list} -typesynopsis {varlist list} -multiple 1 -optional 0
body -type string -optional 0 -help\
"Tcl script"
} "@doc -name Manpage: -url [manpage_tcl lmap]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::lpop
@cmd -name "Built-in: lpop"\
-summary\
"Get and remove an element in a list."\
-help\
"The ${$B}lpop${$N} command acepts a parameter, ${$I}varName${$NI}, which
it interprets as the name of a variable containing a Tcl list.
It also accepts one or more ${$I}indices${$NI} into the list. If no indices
are presented, it defaults to \"${$B}end${$N}\"."
@values -min 1 -max -1
listVar -type string -help\
"Existing list variable name"
index -type indexexpression -default end -optional 1 -multiple 1 -help\
"When presented with a single index, the lpop command addresses
the index'th element in it, removes it from the list and returns
the element.
If index is negative or greater or equal than the number of
elements in the list in the variable ${$I}listVar${$NI}, an error occurs.
If addition index arguments are supplied, then each argument is used
in turn to address an element within a sublist designated by the
previous indexing operation, allowing the script to remove elements
in sublists, similar to lindex and lset."
} "@doc -name Manpage: -url [manpage_tcl lpop]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::lrange
@cmd -name "Built-in: lrange"\
-summary\
"return one or more adjacent elements from a list."\
-help\
"The new list returned consists of elements first through last, inclusive.
The index values first and last are interpreted the same as index values
for the command 'string index', supporting simple index arithmetic and
indices relative to the end of the list.
e.g lrange {a b c} 0 end-1
"
@values -min 3 -max 3
list -type list -help\
"tcl list as a value"
first -type indexexpression -help\
"index expression for first element"
last -type indexexpression -help\
"index expression for last element"
} "@doc -name Manpage: -url [manpage_tcl lrange]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::lrepeat
@cmd -name "Built-in: lrepeat"\
-summary\
"Build a list by repeating elements."\
-help\
"The ${$B}lrepeat${$N} command creates a list of size count * number of
elements by repeating ${$I}count${$NI} times the sequence of elements
${$I}element${$NI} ... count must be a non-negative integer, ${$I}element${$NI}
can be any Tcl value."
@values -min 1 -max -1
count -type integer -range {0 ""}
element -type string -optional 1 -multiple 1
} "@doc -name Manpage: -url [manpage_tcl lrepeat]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::lreplace
@cmd -name "Built-in: lreplace"\
-summary\
"Replace elements in a list with new elements."\
-help\
"${$B}lreplace${$N} returns a new list formed by replacing zero or more
elements of ${$I}list${$NI} with the ${$I}element${$NI} arguments.
${$I}first${$NI} and ${$I}last${$NI} are index values specifying the first
and last elements of the range to replace. The index values ${$I}first${$NI} and
${$I}last${$NI} are interpreted the same as index values for the command ${$B}string index${$N},
supporting simple index arithmetic and indices relative to the end of the list.
0 refers to the first element of the list, and ${$B}end${$N} refers to the last element
of the list.
If either ${$I}first${$NI} or ${$I}last${$NI} is less than zero, it is considered
to refer to before the first element of the list. This allows ${$B}lreplace${$N} to
prepend elements to ${$I}list${$NI}. If either ${$I}first${$NI} or ${$I}last${$NI} indicates
a position greater than the index of the last element of the list, it is
treated as if it is an index one greater than the last element. This allows
${$B}lreplace${$N} to append elements to ${$I}list${$NI}.
If ${$I}last${$NI} is less than ${$I}first${$NI}, then any specified elements will
be inserted into the list before the element specified by ${$I}first${$NI}, with
no elements being deleted.
The ${$I}element${$NI} arguments specify zero or more new elements to be added
to the list in place of those that were deleted. Each ${$I}element${$NI} argument
will become a separate element of the list. If no ${$I}element${$NI} arguments
are specified, then the elements between ${$I}first${$NI} and ${$I}last${$NI} are
simply deleted."
@values -min 3 -max -1
list -type list -help\
"tcl list as a value"
first -type indexexpression
last -type indexexpression
element -type string -optional 1 -multiple 1
} "@doc -name Manpage: -url [manpage_tcl lreplace]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::lremove
@cmd -name "Built-in: lremove"\
-summary\
"Remove elements from a list by index."\
-help\
"lremove returns a new list formed by simultaneously removing zero or
more elements of list at each of the indices given by an arbitrary
number of index arguments. The indices may be in any order and may be
repeated; the element at index will only be removed once. The index
values are interpreted the same as index values for the command
'string index', supporting simple index arithmetic and indices relative
to the end of the list. 0 refers to the first element of the list, and
end refers to the last element of the list."
@values -min 1 -max -1
list -type list -help\
"tcl list as a value"
index -type indexexpression -multiple 1 -optional 1
@seealso -commands {list lappend lassign ledit lindex linsert llength lmap lpop lrange lrepeat lreplace lreverse lsearch lseq lset lsort}
} "@doc -name Manpage: -url [manpage_tcl lremove]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::lreverse
@cmd -name "Built-in: lreverse"\
-summary\
"Reverse the order of a list."\
-help\
"The ${$B}lreverse${$N} command returns a list that has the same elements
as its input list, ${$I}list${$NI}, exept with the elements in reverse
order."
@values -min 1 -max 1
list -type list -help\
"tcl list as a value"
} "@doc -name Manpage: -url [manpage_tcl lreverse]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::lset
@cmd -name "Built-in: lset"\
-summary\
"Change an element in a list."\
-help\
"The ${$B}lset${$N} command accepts a parameter, ${$I}varName${$NI}, which
it interprets as the name of a variable containint a Tcl list. It also
accepts zero or more ${$I}indices${$NI} into the list. The indices may
be presented either consecutively on the command line, or grouped in a
Tcl list and presented as a single argument. Finally, it accepts a new
value for an element of ${$I}varName${$NI}.
If no indices are presented, the command takes the form:
${$B}lset${$N} ${$I}varName${$NI} ${$I}newValue${$NI}
or
${$B}lset${$N} ${$I}varName${$NI} {} ${$I}newValue${$NI}
In this case, ${$I}newValue${$NI} replaces the old value of the variable
${$I}varName${$N}.
When presented with a single index, the ${$B}lset${$N} command treates the
contents of the ${$I}varName${$NI} variable as a Tcl list. It addresses
the ${$I}index${$NI}'th element in it (0 refers to the first element of the
list). When interpreting the list, ${$B}lset${$N} observes the same rules
concerning braces and quotes and backslashes as the Tcl command interpreter;
however; variable substitution and command substitution do not occur.
The command constructs a new list in which the designated element is replaced
with ${$I}newValue${$NI}. This new list is stored in the variable ${$I}varName${$NI},
and is also the return value from the ${$B}lset${$N} command.
If ${$I}index${$NI} is negative or greater than the number of elements in
${$I}$varName${$NI}, then an error occurs.
If ${$I}index${$NI} is equal to the number of elements in ${$I}$varName${$NI},
then the given element is appended to the list.
The interpretation of each simple ${$I}index${$NI} value is the same as for the
command ${$B}string index${$N}, supporting simple index arithmetic and indices
relative to the end of the list.
If additional ${$I}index${$NI} arguments are supplied, then each argument is used
in turn to address an element within a sublist designated by the previous indexing
operation, allowing the script to alter elements in sublists (or append elements to
sublists).
The command,
${$B}lset${$N} a 1 2 newValue
or
${$B}lset${$N} a {1 2} newValue
replaces element 2 of sublist 1 with ${$I}newValue${$NI}.
The integer appearing in each ${$I}index${$NI} argument must be greater than or equal
to zero. The integer appearing in each ${$I}index${$NI} argument must be less than or
equal to the length of the corresponding list. In other wirds, the ${$B}lset${$N} command
can change the size of a list only by appending an element (setting the one after
the current end). If an index is outside the permitted range, an error is reported."
@form -form index
@leaders -min 1 -max -1
listVar -type string -help\
"Existing list variable name"
index -type indexexpression -multiple 1
@values -min 1 -max 1
newValue -type any
@form -form indexlist
@leaders -min 2 -max 2
listVar -type string -help\
"Existing list variable name"
indexList -type list -optional 1 -multiple 0
@values -min 1 -max 1
newValue -type any
} "@doc -name Manpage: -url [manpage_tcl lset]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::lseq
@cmd -name "Built-in: lseq"\
-summary\
"Build a numeric sequence returned as a list."\
-help\
"The ${$B}lseq${$N} command creates a sequence of numeric values using the given
parameters ${$I}start${$NI}, ${$I}end${$NI} and ${$I}step${$NI}. The ${$I}operation${$NI}
argument \"..\" or \"${$B}to${$N}\" defines the range. The \"${$B}count${$N}\" option is
used to defina a count of the number of elements in the list. A short form use of the
command, with a single ${$I}count${$NI} value, will creat a range from 0 to ${$I}count-1${$NI}.
The ${$B}lseq${$N} command can produce both increasing and decreasing sequences.
When both ${$I}start${$NI} and ${$I}end${$NI} are provided without a ${$I}step${$NI} value,
then if ${$I}start${$NI} <= ${$I}end${$NI}, the sequence will be increasing and if
${$I}start${$NI} > ${$I}end${$NI} it will be decreasing. If a ${$I}step${$NI} value is
included, it's sign should agree with the direction of the sequence
(descending -> negative and ascending -> positive), otherwise an empty list is returned.
For example:
${[punk::args::moduledoc::tclcore::argdoc::example {
% lseq 1 to 5 ;#increasing
-> 1 2 3 4 5
% lseq 5 to 1 ;#decreasing
-> 5 4 3 2 1
% lseq 6 to 1 by 2 ;#decreasing, step wrong sign, empty list
% lseq 1 5 by 0 ;#all step sizes of 0 produce an empty list
}]}
The numeric arguments ${$I}start${$NI}, ${$I}end${$NI}, ${$I}step${$NI} and ${$I}count${$NI}, may
also be a valid expression. The expression will be evaluated and the numeric result will
be used. An expression that does not evaluate to a number will produce an invalid argument error.
${$I}Start${$NI} defines the initial value and ${$I}end${$NI} defines the limit, not necessarily
the last value. ${$B}lseq${$N} produces a list with ${$B}count${$N} elements and if ${$B}count${$N}
is not supplied, it is computed as:
count = int( (end - start + step) / step)
"
@form -form range
@leaders -min 0 -max 0
@values -min 2 -max 5
start -type number|expr
..|to -type string -choices {.. to} -optional 1
end -type number|expr
"by step" -type {literal(by) number|expr} -optional 1
@form -form start_count
@leaders -min 0 -max 0
@values -min 3 -max 5
start -type number|expr
count -type literal
countelements -type number|expr
"by step" -type {literal(by) number|expr} -optional 1
@form -form count
@leaders -min 0 -max 0
@values -min 1 -max 3
countelements -type number|expr
"by step" -type {literal(by) number|expr} -optional 1
} "@doc -name Manpage: -url [manpage_tcl lreverse]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::lsearch
@cmd -name "Built-in: lsearch"\
-summary\
"See if a list contains a particular element."\
-help\
"This command searches the elements of list to see if one of them matches pattern. If so, the command returns
the index of the first matching element (unless the options -all or -inline are specified.) If not, the command
returns -1 or (if options -all or -inline are specified) the empty string. The option arguments indicates how
the elements of the list are to be matched against pattern.
(documentation incomplete - punk::args fixes required for grouped mutually exlusive options and prefix calculation)
"
@leaders -min 0 -max 0
@opts -type none -parsekey "-MATCHSTYLE" -group "MATCHING STYLE OPTIONS" -grouphelp\
"If all matching style options are omitted, the default matching style is -glob.
If more than one matching style is specified, the last matching style given
takes precedence."
-exact -typedefaults "-exact" -help\
"Pattern is a literal string that is compared for exact equality against each list element."
-glob -typedefaults "-glob" -default "-glob" -help\
"Pattern is a glob-style pattern which is matched against each list element using the same
rules as the string match command."
-regexp -typedefaults "-regexp" -help\
"Pattern is treated as a regular expression and matched against each list element using the
rules described in the re_syntax reference page."
-sorted -typedefaults "-sorted" -help\
"The list elements are in sorted order. If this option is specified, lsearch will use a more
efficient searching algorithm to search list. If no other options are specified, list is
assumed to be sorted in increasing order, and to contain ASCII strings. This option is
mutually exclusive with -glob and -regexp, and is treated exactly like -exact when either
-all or -not are specified."
@opts -type string -parsekey "" -group "GENERAL MODIFIER OPTIONS"
-all -type none -help\
"Changes the result to be the list of all matching indices (or all matching values if -inline is specified as well.)
If indices are returned, the indices will be in ascending numeric order. If values are returned, the order of the
values will be the order of those values within the input list."
-inline -type none -help\
"The matching value is returned instead of its index (or an empty string if no value matches.) If -all is also
specified, then the result of the command is the list of all values that matched."
-not -type none
-start -type none
@opts -type none -parsekey "-CONTENTOPTION" -group "CONTENTS DESCRIPTION OPTIONS" -grouphelp\
"These options describe how to interpret the items in the list being searched. They are only meaningful when
used with the -exact and -sorted options. If more than one is specified, the last one takes precedence.
The default is -ascii."
-ascii -typedefaults "-ascii" -default "-ascii" -help\
"The list elements are to be examined as Unicode strings (the name is for backward-compatibility reasons.)"
-dictionary -typedefaults "-dictionary" -help\
"The list elements are to be compared using dictionary-style comparisons (see lsort for a fuller
description). Note that this only makes a meaningful difference from the -ascii option when the -sorted
option is given, because values are only dictionary-equal when exactly equal."
-integer -typedefaults "-integer" -help\
"The list elements are to be compared as integers."
-nocase -typedefaults "-nocase" -help\
"Causes comparisons to be handled in a case-insensitive manner. Has no effect if combined with the
-dictionary, -integer, or -real options."
-real -typedefaults "-real" -help\
"The list elements are to be compared as floating-point values."
# -groupdefault "-increasing" ???
@opts -type none -parsekey "-SORTOPTION" -group "SORTED LIST OPTIONS" -grouphelp\
"These options (only meaningful with the -sorted option) specify how the list is sorted. If more than one is
given, the last one takes precedence. The default option is -increasing."
-decreasing -typedefaults "-decreasing" -help\
" The list elements are sorted in decreasing order. This option is only meaningful when used with -sorted."
-increasing -typedefaults "-increasing" -default "-increasing" -help\
" The list elements are sorted in increasing order. This option is only meaningful when used with -sorted."
-bisect -typedefaults "-bisect" -help\
" Inexact search when the list elements are in sorted order. For an increasing list the last index where
the element is less than or equal to the pattern is returned. For a decreasing list the last index where
the element is greater than or equal to the pattern is returned. If the pattern is before the first
element or the list is empty, -1 is returned. This option implies -sorted and cannot be used with either
-all or -not."
@opts -type string -parsekey "" -group "NESTED LIST OPTIONS" -grouphelp\
"These options are used to search lists of lists. They may be used with any other options."
-stride -type integer -default 1 -typesynopsis strideLength -help\
"If this option is specified, the list is treated as consisting of groups of ${$I}strideLength${$NI} elements and the
groups are searched by either their first element or, if the ${$B}-index${$N} option is used, by the element within
each group given by the first index passed to -index (which is then ignored by -index). The resulting
index always points to the first element in a group.
The list length must be an integer multiple of strideLength, which in turn must be at least 1. A
strideLength of 1 is the default and indicates no grouping."
-index -type list -typesynopsis indexList -help\
"This option is designed for use when searching within nested lists. The indexList argument gives a path of
indices (much as might be used with the lindex or lset commands) within each element to allow the location
of the term being matched against."
-subindices -type none -help\
"If this option is given, the index result from this command (or every index result when -all is also
specified) will be a complete path (suitable for use with lindex or lset) within the overall list to the
term found. This option has no effect unless the -index is also specified, and is just a convenience
short-cut."
@opts -parsekey "" -group ""
@values -min 2 -max 2
list -type list
pattern -type string
} "@doc -name Manpage: -url [manpage_tcl lsearch]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::lsort
@cmd -name "Built-in: lsort"\
-summary\
"Sort the elements of a list."\
-help\
"This command sorts the elements of ${$I}list${$NI}, returning a new list
in sorted order. The implementation of the ${$B}lsort${$N} command uses
the merge-sort algorithem which is a stable sort that has O(n log n)
performance characteristics.
NOTES:
The options to ${$B}lsort${$N} only control what sort of comparison is used, and
do not necessarily constrain what the values themselves actually are.
This distinction is only noticeable when the list to be sorted has fewer
than two elements.
The lsort command is reentrant, meaning it is safe to use as part of the
implementation of a command used in the ${$B}-command${$N} option."
@leaders -min 0 -max 0
@opts
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
-ascii -type none -help\
"Use string comparison with Unicode code-point collation order (the name
is for backward-compatibility reasons.) This is the default."
-dictionary -type none -help\
"Use dictionary-style comparison. This is the same as ${$B}-ascii${$N} except (a)
case is ignored except as a tie-breaker and (b) if two strings contain
embedded numbers, the numbers compare as integers, not characters. For
example, in ${$B}-dictionary${$N} mode, bigBoy sorts between bigbang and bigboy,
and x10y sorts between x9y and x11y. Overrides the ${$B}-nocase${$N} option."
-integer -type none -help\
"Convert list elements to integers and use integer comparison."
-real -type none -help\
"Convert list elements to floating-point values and use floating comparison."
-command -type string -help\
"Use command as a comparison command. To compare two elements, evaluate a
Tcl script consisting of command with the two elements appended as
additional arguments. The script should return an integer less than,
equal to, or greater than zero if the first element is to be considered
less than, equal to, or greater than the second, respectively."
-increasing -type none -help\
"Sort the list in increasing order (\"smallest\" items first).
This is the default."
-decreasing -type none -help\
"Sort the list in decreasing order (\"largest\" items first)."
-indices -type none -help\
"Return a list of ${$I}indices${$NI} into list in sorted order instead of the
values themselves."
-index -type indexList -help\
{If this option is specified, each of the elements of list must itself be
a proper Tcl sublist (unless -stride is used). Instead of sorting based
on whole sublists, lsort will extract the indexList'th element from each
sublist (as if the overall element and the indexList were passed to lindex)
and sort based on the given element.
For example,
${[punk::args::moduledoc::tclcore::argdoc::example {
lsort -integer -index 1 \
{{First 24} {Second 18} {Third 30}} }]}
returns ${$B}{Second 18} {First 24} {Third 30}${$N},
${[punk::args::moduledoc::tclcore::argdoc::example {
lsort -index end-1 \
{{a 1 e i} {b 2 3 f g} {c 4 5 6 d h}} }]}
returns ${$B}{c 4 5 6 d h} {a 1 e i} {b 2 3 f 5}${$N}, and
${[punk::args::moduledoc::tclcore::argdoc::example {
lsort -index {0 1} {
{{b i g} 12345}
{{d e m o} 34512}
{{c o d e} 54321}
}}]}
returns ${$B}{{d e m o} 34512} {{b i g} 12345} {{c o d e} 54321}${$N}
(because e sorts before i which sorts before o.) This option is much more
efficient than using ${$B}-command${$N} to achieve the same effect.}
-stride -type integer -range {2 ""} -help\
{If this option is specified, the list is treated as consisting of groups
of strideLength elements and the groups are sorted by either their first
element or, if the ${$B}-index${$N} option is used, by the element within each
group given by the first index passed to ${$B}-index${$N} (which is then ignored
by ${$B}-index${$N}). Elements always remain in the same position within their
group.
The list length must be an integer multiple of the strideLength, which
in turn must be at least 2.
For example,
${[punk::args::moduledoc::tclcore::argdoc::example {
lsort -stride 2 {carrot 10 apple 50 banana 25} }]}
returns "apple 50 banana 25 carrot 10", and
${[punk::args::moduledoc::tclcore::argdoc::example {
lsort -stride 2 -index 1 -integer {carrot 10 apple 50 banana 25} }]}
returns "carrot 10 banana 25 apple 50".}
-nocase -type none -help\
"Causes comparisons to be handled in a case-insensitive manner. Has no
effect if combined with the ${$B}-dictionary${$N}, ${$B}-integer${$N}, or
${$B}-real${$N} options."
-unique -type none -help\
"If this option is specified, then only the last set of duplicate elements
found in the list will be retained. Note that duplicates are determined
relative to the comparison used in the sort. Thus if ${$B}-index 0${$N} is
used, ${$B}{1 a}${$N} and ${$B}{1 b}${$N} would be considered duplicates and
only the second element, ${$B}{1 b}${$N}, would be retained."
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
@values -min 1 -max 1
list -type list -help\
"tcl list as a value"
} "@doc -name Manpage: -url [manpage_tcl lsort]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
}
############################################################################################################################################################
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# COMMANDS M-Z
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
############################################################################################################################################################
namespace eval argdoc {
#PACKAGE
#JJJ
#define subcommand documentation first
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id "(shared)::package"
@values
#used by 'package present' and 'package require' and (with override of -optional) 'package vsatisfies'
requirement -type packagerequirement -multiple 1 -optional 1 -help\
"A requirement string checks, if a compatible version number of a package is present. Most commands
accept a list of requirement strings where the highest suitable version is matched.
${$I}min${$NI}
This form is called min-bounded
${$I}min-${$NI}
This form is called min-unbound
${$I}min-max${$NI}
This form is called bounded
where min and max are valid version numbers. The legacy syntax is a special case of the extended
syntax, keeping backward compatibility. Regarding satisfaction the rules are:
1. The version has to pass at least one of the listed requirements to be satisfactory.
2. A version satisfies a bounded requirement when
1. For min equal to the max if, and only if the version is equal to the min
2. Otherwise if, and only if the version is greater than or equal to the min, and less than the max,
where both min and max have been padded internally with a0. Note that while the comparison to
min is inclusive, the comparison to max is exclusive.
3. A min-bounded requirement is a bounded requirement in disguise, with the max part implicitly
specified as the next higher major version number of the min part. A version satisfies it per the rules
above.
4. A version satisfies a min-unbound requirement if, and only if it is greater than or equal to the min,
where the min has been padded internally with a0. There is no constraint to a maximum."
#used by 'package present' 'package require' etc - be careful to override -optional as needed
version -type packageversion -optional 0 -help\
"Version numbers consist of one or more decimal numbers separated by dots, such as 2 or 1.162 or 3.1.13.1.
The first number is called the major version number. Larger numbers correspond to later versions of a package, with
leftmost numbers having greater significance. For example, version 2.1 is later than 1.3 and version 3.4.6 is later
than 3.3.5. Missing fields are equivalent to zeroes: version 1.3 is the same as version 1.3.0 and 1.3.0.0, so it is
earlier than 1.3.1 or 1.3.0.2. In addition, the letters a (alpha) and/or b (beta) may appear exactly once to
replace a dot for separation. These letters semantically add a negative specifier into the version, where a is -2,
and b is -1. Each may be specified only once, and a or b are mutually exclusive in a specifier. Thus 1.3a1
becomes (semantically) 1.3.-2.1, 1.3b1 is 1.3.-1.1. Negative numbers are not directly allowed in version specifiers.
A version number not containing the letters a or b as specified above is called a stable version, whereas presence
of the letters causes the version to be called is unstable. A later version number is assumed to be upwards compatible
with an earlier version number as long as both versions have the same major version number. For example, Tcl scripts
written for version 2.3 of a package should work unchanged under versions 2.3.2, 2.4, and 2.5.1. Changes in the major
version number signify incompatible changes: if code is written to use version 2.1 of a package, it is not guaranteed
to work unmodified with either version 1.7.3 or version 3.1."
}
#for retrieval using:
#${[punk::args::resolved_def -form 1 -types values (shared)::package requirement]}
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id "::package files"
@cmd -name "Built-in: ::package files"\
-summary\
"List files forming part of package."\
-help\
"Lists all files forming part of package. Auto-loaded files are not included in this list,
only files which were directly sourced during package initialization. The list order
corresponds with the order in which the files were sourced."
@values -min 1 -max 1
package -type string
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl package]"
punk::args::define {
@id -id "::package forget"
@cmd -name "Built-in: ::package forget"\
-summary\
"Remove package info from the package database."\
-help\
"Removes all information about each specified package from this interpreter,
including information provided by both ${$B}package ifneeded${$N} and ${$B}package provide${$N}."
@values -min 0 -max -1
package -type string -multiple 1 -optional 1
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl package]"
punk::args::define {
@id -id "::package ifneeded"
@cmd -name "Built-in: ::package ifneeded"\
-summary\
"Query/configure a package script."\
-help\
"This command typically appears only in system configuration scripts to set up the package database.
It indicates that a particular version of a particular package is available if needed, and that the
package can be added to the interpreter by executing script. The script is saved in a database for
use by subsequent package require commands; typically, script sets up auto-loading for the commands
in the package (or calls load and/or source directly), then invokes package provide to indicate that
the package is present. There may be information in the database for several different versions of a
single package. If the database already contains information for package and version, the new script
replaces the existing one. If the script argument is omitted, the current script for version version
of package package is returned, or an empty string if no package ifneeded command has been invoked
for this package and version."
@values -min 2 -max 3
package -type string
${[punk::args::resolved_def -types values (shared)::package version]}
script -type script -optional 1
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl package]"
punk::args::define {
@id -id "::package names"
@cmd -name "Built-in: ::package names"\
-summary\
"List package names (scanned so far)"\
-help\
"Returns a list of the names of all packages in the interpreter for which a version has been provided
(via package provide) or for which a package ifneeded script is available. The order of elements in
the list is arbitrary."
@values -min 0 -max 0
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl package]"
punk::args::define {
@id -id "::package present"
@cmd -name "Built-in: ::package present"\
-summary\
"Test package presence vs requirement(s)."\
-help\
"This command is equivalent to package require except that it does not try and load the package
if it is not already loaded."
@form -form requirements
@opts
@values -min 1 -max -1
package -type string
${[punk::args::resolved_def -types values (shared)::package requirement]}
@form -form exact
@opts
#-exact is not optional for this form
-exact -type none -optional 0
@values -min 2 -max 2
package -type string
${[punk::args::resolved_def -types values (shared)::package version]}
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl package]"
punk::args::define {
@id -id "::package provide"
@cmd -name "Built-in: ::package provide"\
-summary\
"Declare package provision with version or query if provided."\
-help\
"This command is invoked to indicate that version version of package package is now present in the interpreter.
It is typically invoked once as part of an ifneeded script, and again by the package itself when it is finally
loaded. An error occurs if a different version of package has been provided by a previous package provide
command. If the version argument is omitted, then the command returns the version number that is currently
provided, or an empty string if no package provide command has been invoked for package in this interpreter."
@values -min 1 -max 2
package -type string
${[punk::args::resolved_def -types values -override {version {-optional 1}} (shared)::package version]}
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl package]"
punk::args::define {
@id -id "::package require"
@cmd -name "Built-in: ::package require"\
-summary\
"Source/load a package into the interp"\
-help\
"This command is typically invoked by Tcl code that wishes to use a particular version of a particular package.
The arguments indicate which package is wanted, and the command ensures that a suitable version of the package
is loaded into the interpreter. If the command succeeds, it returns the version number that is loaded;
otherwise it generates an error.
A suitable version of the package is any version which satisfies at least one of the requirements as defined in
for the ${$I}requirment${$NI} argument below. If multiple versions are suitable the implementation with the highest version is
chosen. This last part is additionally influenced by the selection mode set with package prefer.
In the stable selection mode the command will select the highest stable version satisfying the requirements,
if any. If no stable version satisfies the requirements, the highest unstable version satisfying the requirements
will be selected. In the latest selection mode the command will accept the highest version satisfying all the
requirements, regardless of its stableness.
If a version of package has already been provided (by invoking the package provide command), then its version
number must satisfy the requirements and the command returns immediately. Otherwise, the command searches the
database of information provided by previous package ifneeded commands to see if an acceptable version of the
package is available. If so, the script for the highest acceptable version number is evaluated in the global
namespace; it must do whatever is necessary to load the package, including calling package provide for the
package. If the package ifneeded database does not contain an acceptable version of the package and a package
unknown command has been specified for the interpreter then that command is evaluated in the global namespace;
when it completes, Tcl checks again to see if the package is now provided or if there is a package ifneeded
script for it. If all of these steps fail to provide an acceptable version of the package, then the command
returns an error.
"
@form -form requirements
@opts
@values -min 1 -max -1
package -type string
${[punk::args::resolved_def -types values (shared)::package requirement]}
@form -form exact
@opts
#-exact is not optional for this form
-exact -type none -optional 0
@values -min 2 -max 2
package -type string
${[punk::args::resolved_def -types values -override {version {-optional 0}} (shared)::package version]}
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl package]"
punk::args::define {
@id -id "::package unknown"
@cmd -name "Built-in: ::package unknown"\
-summary\
"Set/Query the package unknown handler function."\
-help\
"This command supplies a last resort command to invoke during ${$B}package require${$N} if no suitable version
of a package can be found in the ${$B}package ifneeded${$N} database. If the ${$I}command${$NI} argument is supplied, it
contains the first part of a command; when the command is invoked during a package require command, Tcl
appends one or more additional arguments giving the desired package name and requirements. For example,
if ${$I}command${$NI} is ${$B}foo bar${$N} and later the command ${$B}package require test 2.4${$N} is invoked, then Tcl will execute
the command ${$B}foo bar test 2.4${$N} to load the package. If no requirements are supplied to the ${$B}package require${$N}
command, then only the name will be added to invoked command. If the ${$B}package unknown${$N} command is invoked
without a ${$I}command${$NI} argument, then the current ${$B}package unknown${$N} script is returned, or an empty string if
there is none. If ${$I}command${$NI} is specified as an empty string, then the current ${$B}package unknown${$N} script is
removed, if there is one."
@values -min 0 -max 1
command -type string -optional 1
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl package]"
punk::args::define {
@id -id "::package vcompare"
@cmd -name "Built-in: ::package vcompare"\
-summary\
"Compare two version numbers."\
-help\
"Compares the two version numbers given by version1 and version2.
Returns -1 if version1 is an earlier version than version2, 0 if
they are equal, and 1 if version1 is later than version2."
@values -min 2 -max 2
${[punk::args::resolved_def -types values -override {version {name version1 -optional 0}} (shared)::package version]}
#don't reuse def for version2 - we don't need to show the version help twice
version2 -type packageversion -optional 0 -help "(as above)"
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl package]"
punk::args::define {
@id -id "::package versions"
@cmd -name "Built-in: ::package versions"\
-summary\
"List versions for package (if scanned)"\
-help\
"Returns a list of all the version numbers of package for which information
has been provided by ${$B}package ifneeded${$N} commands."
@values -min 1 -max 1
package -type string
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl package]"
punk::args::define {
@id -id "::package vsatisfies"
@cmd -name "Built-in: ::package versions"\
-summary\
"List versions for package (if scanned)"\
-help\
"Returns a list of all the version numbers of package for which information
has been provided by ${$B}package ifneeded${$N} commands."
@values -min 2 -max -1
${[punk::args::resolved_def -types values -override {version {-optional 0}} (shared)::package version]}
${[punk::args::resolved_def -types values -override {requirement {-optional 0}} (shared)::package requirement]}
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl package]"
punk::args::define {
@id -id "::package prefer"
@cmd -name "Built-in: ::package prefer"\
-summary\
"Configure/query latest vs stable for package require."\
-help\
"With no arguments, the commands returns either latest or stable, whichever describes the current mode
of selection logic used by package require.
When passed the argument latest, it sets the selection logic mode to latest.
When passed the argument stable, if the mode is already stable, that value is kept. If the mode is already
latest, then the attempt to set it back to stable is ineffective and the mode value remains latest.
When passed any other value as an argument, raise an invalid argument error.
When an interpreter is created, its initial selection mode value is set to stable unless the environment
variable TCL_PKG_PREFER_LATEST is set (to any value) or the Tcl package itself is unstable. Otherwise the
initial (and permanent) selection mode value is set to latest."
@values -min 0 -max 1
stability -type {literalprefix(latest)|literalprefix(stable)} -optional 1
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl package]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# ::package
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
set PACKAGE_CHOICES [list files forget ifneeded names present provide require unknown vcompare versions vsatisfies prefer]
#manual synopses for subcommands not yet defined
set PACKAGE_CHOICELABELS [subst -novariables {
files "package files [punk::ansi::a+ italic]package[punk::ansi::a+ noitalic]"
names "package names"
}]
set PACKAGE_CHOICEINFO [dict create]
foreach sub $PACKAGE_CHOICES {
#default for all
dict set PACKAGE_CHOICEINFO $sub {{doctype native}}
}
foreach id [punk::args::get_ids "::package *"] {
if {[llength $id] == 2} {
lassign $id _ sub
dict set PACKAGE_CHOICEINFO $sub {{doctype native} {doctype punkargs}}
#override manual synopsis entry
#puts stderr "override manual synopsis entry with [punk::ns::synopsis "::package $sub"]"
dict set PACKAGE_CHOICELABELS $sub [punk::ansi::a+ normal][punk::ns::synopsis "::package $sub"]
}
}
punk::args::define {
@id -id ::package
@cmd -name "Built-in: ::package"\
-summary\
"Facilities for package loading and version control."\
-help\
"This command keeps a simple database of the packages available for use by the current
interpreter and how to load them into the interpreter. It supports multiple versions of
each package and arranges for the correct version of a package to be loaded based on
what is needed by the application. This command also detects and reports version clashes.
Typically, only the package require and package provide commands are invoked in normal
Tcl scripts; the other commands are used primarily by system scripts that maintain the
package database."
@leaders -min 1 -max 1
subcommand -type string\
-choicecolumns 2\
-choicegroups {
"" {files forget names present provide require vcompare versions vsatisfies}
configuration {prefer unknown ifneeded}
}\
-choicelabels {${$PACKAGE_CHOICELABELS}}\
-choiceinfo {${$PACKAGE_CHOICEINFO}}
@values -unnamed true
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl package]"\
{@examples -help {
To state that a Tcl script requires the Tk and http packages, put this at the top of the script:
${[punk::args::moduledoc::tclcore::argdoc::example {
package require Tk
package require http
}]}
To test to see if the Snack package is available and load if it is (often useful for optional
enhancements to programs where the loss of the functionality is not critical) do this:
${[punk::args::moduledoc::tclcore::argdoc::example {
if {[catch {package require Snack}]} {
# Error thrown - package not found.
# Set up a dummy interface to work around the absence
} else {
# We have the package, configure the app to use it
}
}]}
}}
}
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
namespace eval argdoc {
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::proc
@cmd -name "Built-in: proc"\
-summary\
"Create a Tcl procedure."\
-help\
"The ${$B}proc${$N} command creates a new Tcl procedure named name, replacing
any existing command or procedure there may have been by that name. Whenever
the new command is invoked, the contents of ${$I}body${$NI} will be executed by
the Tcl interpreter. Normally, ${$I}name${$NI} is unqualified (does not include
the names of any containing namespaces), and the new procedure is created in
the current namespace. If ${$I}name${$NI} includes any namespace qualifiers
the procdure is created in the specified namesapce. ${$I}Args${$NI} specifies
the formal arguments to the procedure. It consists of a list, possibly empty,
each of whose elements specifies on argument. Each argument specifier is also
a list with either one or two fields. If there is only a single field in the
specifier then it is the name of the argument; if there are two fields, then
the first is the argument name and the second is its default value. Arguments
with default values that are followed by non-defaulted arguments become
required arguments; enough actual arguments must be supplied to allow all
arguments up to and including the last required formal argument.
When ${$I}name${$NI} is invoked a local variable will be created for each of
the formal arguments to the procedure; its value will be the value of the
corresponding argument in the invoking command or the argument's default
value. Actual arguments are assigned to formal arguments strictly in order.
Arguments with default values need not be specified in a procedure invocation.
However, there must be enough actual arguments for all the formal arguments
that do not have defaults, and there must not be any extra actual arguments.
Arguments with default values that are followed by non-defaulted arguments
become de-facto required arguments, though this may change in a future version
of Tcl; portable code should ensure that all optional arguments come after
all required arguments.
There is one special case to permit procedures with variable number of
arguments. If the last formal argument has the name \"${$B}args${$N}\", then a
call to the procedure may contain more actual arguments than the procedure
has formal arguments. In this case, all of the actual arguments starting at
the one that would be assigned to ${$B}args${$N} are combined into a list
(as if the ${$B}list${$N} command had been used); this combined value is assigned
to the local variable ${$B}args${$N}.
When ${$I}body${$NI} is being executed, variable names normally refer to local
variables, which are created automatically when referenced, and deleted when
the procedure returns. One local variable is automatically created for each of
the procedure's arguments. Other variables can only be accessed by invoking
one of ${$B}global${$N}, ${$B}variable${$N}, ${$B}upvar${$N} or ${$B}namespace upvar${$N}
commands. The current namespace when ${$I}body${$NI} is executed will be the
namespace that the procedure's name exists in, which will be the namespace that
it was created in unless it has been changed with ${$B}rename${$N}.
The ${$B}proc${$N} command returns an empty string. When a procedure is invoked,
the procedure's return value is the value specified in a ${$B}return${$N} command.
If the procedure does not execute an explicit ${$B}return${$N}, then its return
value is the value of the last command executed in the procedure's body. If an
error occurs while executing the procedure body, then the procedure-as-a-whole
will return that same error."
@values -min 3 -max 3
name -type string
#todo - list elements must be length 1 or length 2
args -type list
body -type script
} "@doc -name Manpage: -url [manpage_tcl proc]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::puts
@cmd -name "Built-in: puts"\
-summary\
"Write to a channel."\
-help\
"The ${$B}puts${$N} command has been superceded by the ${$B}chan puts${$N} command which
supports the same syntax and options."
@opts -prefix 0
-nonewline -type none
@values -min 1 -max 2
channel -type string -optional 1
string -type string
} "@doc -name Manpage: -url [manpage_tcl puts]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::pwd
@cmd -name "Built-in: pwd"\
-summary\
"Return the absolute path of the current working directory."\
-help\
"Returns the absolute path name of the current working directory.
(This is a process-wide value)
${$B}EXAMPLE${$N}
Sometimes it is useful to change to a known directory when running some external
command using exec, but it is important to keep the application usually running
in the directory that it was started in (unless the user specifies otherwise)
since that minimizes user confusion. The way to do this is to save the current
directory while the external command is being run:
${[punk::args::moduledoc::tclcore::argdoc::example {
set tarFile [file normalize somefile.tar]
set savedDir [pwd]
cd /tmp
exec tar -xf $tarFile
cd $savedDir
}]}"
@leaders -min 0 -max 0
@values -min 0 -max 0
} "@doc -name Manpage: -url [manpage_tcl pwd]"\
{@examples -help {
Sometimes it is useful to change to a known directory when running some external
command using exec, but it is important to keep the application usually running
in the directory that it was started in (unless the user specifies otherwise)
since that minimizes user confusion. The way to do this is to save the current
directory while the external command is being run:
${[punk::args::moduledoc::tclcore::argdoc::example {
set tarFile [file normalize somefile.tar]
set savedDir [pwd]
cd /tmp
exec tar -xf $tarFile
cd $savedDir
}]}
}
}
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::read
@cmd -name "Built-in: read"\
-summary\
"Read from a channel."\
-help\
"The ${$B}read${$N} command has been superceded by the ${$B}chan read${$N} command which supports
the same syntax and options."
@form -form read
@opts
-nonewline -type none
@values -min 1 -max 1
channel
@form -form readchars
@values -min 1 -max 2
channel
numChars -type integer -optional 1
} "@doc -name Manpage: -url [manpage_tcl read]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::rename
@cmd -name "Built-in: rename"\
-summary\
"Rename or delete a command."\
-help\
"Rename the command that used to be called ${$I}oldName${$NI} so that it is now called ${$I}newName${$NI}. If
${$I}newName${$NI} is an empty string then ${$I}oldName${$NI} is deleted. ${$I}oldName${$NI} and ${$I}newName${$NI} may include
namespace qualifiers (names of containing namespaces). If a command is renamed into a
different namespace, future invocations of it will execute in the new namespace. The
${$B}rename${$N} command returns an empty string as result."
@values -min 2 -max 2
oldName -type string
newName -type string
} "@doc -name Manpage: -url [manpage_tcl rename]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::return
@cmd -name "Built-in: return"\
-summary\
"Return from a procedure, or set return code of script."\
-help\
"In its simplest usage, the return command is used without options in the body of a
procedure to immediately return control to the caller of the procedure. If a result
argument is provided, its value becomes the result of the procedure passed back to
the caller. If result is not specified then an empty string will be returned to the
caller as the result of the procedure.
The return command serves a similar function within script files that are evaluated
by the source command. When source evaluates the contents of a file as a script, an
invocation of the return command will cause script evaluation to immediately cease,
and the value result (or an empty string) will be returned as the result of the
source command.
In addition to the result of a procedure, the return code of a procedure may also be
set by return through use of the -code option. In the usual case where the -code
option is not specified the procedure will return normally. However, the -code option
may be used to generate an exceptional return from the procedure.
${$B}RETURN OPTIONS${$N}
In addition to a result and a return code, evaluation of a command in Tcl also produces
a dictionary of return options. In general usage, all option value pairs given as
arguments to return become entries in the return options dictionary, and any values at
all are acceptable except as noted below. The catch command may be used to capture all
of this information the return code, the result, and the return options dictionary
that arise from evaluation of a script.
As documented above, the -code entry in the return options dictionary receives special
treatment by Tcl. There are other return options also recognized and treated specially
by Tcl. They are: -errorcode, -errorinfo, -errorstack, -level, -options.
${$B}RETURN CODE HANDLINE MECHANISMS${$N}
Return codes are used in Tcl to control program flow. A Tcl script is a sequence of Tcl
commands. So long as each command evaluation returns a return code of TCL_OK, evaluation
will continue to the next command in the script. Any exceptional return code (non-TCL_OK)
returned by a command evaluation causes the flow on to the next command to be interrupted.
Script evaluation ceases, and the exceptional return code from the command becomes the
return code of the full script evaluation. This is the mechanism by which errors during
script evaluation cause an interruption and unwinding of the call stack. It is also the
mechanism by which commands like break, continue, and return cause script evaluation to
terminate without evaluating all commands in sequence.
Some of Tcl's built-in commands evaluate scripts as part of their functioning. These
commands can make use of exceptional return codes to enable special features. For example,
the built-in Tcl commands that provide loops such as while, for, and foreach evaluate
a script that is the body of the loop. If evaluation of the loop body returns the return
code of TCL_BREAK or TCL_CONTINUE, the loop command can react in such a way as to give the
break and continue commands their documented interpretation in loops.
Procedure invocation also involves evaluation of a script, the body of the procedure.
Procedure invocation provides special treatment when evaluation of the procedure body
returns the return code TCL_RETURN. In that circumstance, the -level entry in the return
options dictionary is decremented. If after decrementing, the value of the -level entry is
0, then the value of the -code entry becomes the return code of the procedure. If after
decrementing, the value of the -level entry is greater than zero, then the return code of
the procedure is TCL_RETURN. If the procedure invocation occurred during the evaluation of
the body of another procedure, the process will repeat itself up the call stack,
decrementing the value of the -level entry at each level, so that the code will be the
return code of the current command level levels up the call stack. The source command
performs the same handling of the TCL_RETURN return code, which explains the similarity of
return invocation during a source to return invocation within a procedure.
The return code of the return command itself triggers this special handling by procedure
invocation. If return is provided the option -level 0, then the return code of the return
command itself will be the value code of the -code option (or TCL_OK by default). Any
other value for the -level option (including the default value of 1) will cause the return
code of the return command itself to be TCL_RETURN, triggering a return from the enclosing
procedure."
@form -form basic
@form -form code
@form -form options
@leaders -form {basic code options} -min 0 -max 0
@opts -form {code options}
-code -form {code options} -default 0\
-type int\
-typesynopsis {${$I}choice${$NI}|<${$I}int${$NI}>}\
-help\
"When a value is given outside of the listed choices, it's value must be an
integer; it will be returned as the return code for the current procedure.
Applications and packages should use values in the range 5 to 1073741823
(0x3fffffff) for their own purposes. Values outside this range are reserved
for use by Tcl.
When a procedure wants to signal that it has received invalid arguments from
its caller, it may use return -code error with result set to a suitable error
message. Otherwise usage of the return -code option is mostly limited to
procedures that implement a new control structure.
The return -code command acts similarly within script files that are evaluated
by the source command. During the evaluation of the contents of a file as a
script by source, an invocation of the return -code code command will cause the
return code of source to be code."\
-choicecolumns 2\
-choiceprefix 0\
-choicerestricted 0\
-choices {ok 0 error 1 return 2 break 3 continue 4}\
-choicelabels {
ok\
" Normal return: same as if the option is omitted.
The return code of the procedure is 0 (TCL_OK)."
error\
" Error return: the return code of the procedure is
1 (TCL_ERROR). The procedure command behaves in
its calling context as if it were the command
error result. See below for additional options."
return\
" The return code of the procedure is 2
(TCL_RETURN). The procedure command behaves in its
calling context as if it were the command return
(with no arguments)."
break\
" The return code of the procedure is 3 (TCL_BREAK).
The procedure command behaves in its calling
context as if it were the command break."
continue\
"The return code of the procedure is 4
(TCL_CONTINUE). The procedure command behaves in
its calling context as if it were the command
continue."
}
-errorcode -form options -type list -help\
"The -errorcode option receives special treatment only when the value of the
-code option is TCL_ERROR. Then the list value is meant to be additional
information about the error, presented as a Tcl list for further processing
by programs. If no -errorcode option is provided to return when the -code
error option is provided, Tcl will set the value of the -errorcode entry in
the return options dictionary to the default value of NONE. The -errorcode
return option will also be stored in the global variable errorCode."
-errorinfo -form options -type list -typesynopsis ${$I}info${$NI} -help\
"The -errorinfo option receives special treatment only when the value of the
-code option is TCL_ERROR. Then info is the initial stack trace, meant to
provide to a human reader additional information about the context in which
the error occurred. The stack trace will also be stored in the global
variable errorInfo. If no -errorinfo option is provided to return when the
-code error option is provided, Tcl will provide its own initial stack trace
value in the entry for -errorinfo. Tcl's initial stack trace will include
only the call to the procedure, and stack unwinding will append information
about higher stack levels, but there will be no information about the
context of the error within the procedure. Typically the info value is
supplied from the value of -errorinfo in a return options dictionary
captured by the catch command (or from the copy of that information stored in
the global variable errorInfo)."
-errorstack -form options -type list -help\
"The -errorstack option receives special treatment only when the value of the
-code option is TCL_ERROR. Then list is the initial error stack, recording
actual argument values passed to each proc level. The error stack will also
be reachable through info errorstack. If no -errorstack option is provided to
return when the -code error option is provided, Tcl will provide its own
initial error stack in the entry for -errorstack. Tcl's initial error stack
will include only the call to the procedure, and stack unwinding will append
information about higher stack levels, but there will be no information about
the context of the error within the procedure. Typically the list value is
supplied from the value of -errorstack in a return options dictionary
captured by the catch command (or from the copy of that information from info
errorstack)."
-level -form options -type integer -range {0 ""} -typesynopsis ${$I}level${$NI} -help\
"The -level and -code options work together to set the return code to be
returned by one of the commands currently being evaluated. The level value must
be a non-negative integer representing a number of levels on the call stack. It
defines the number of levels up the stack at which the return code of a command
currently being evaluated should be code. If no -level option is provided, the
default value of level is 1, so that return sets the return code that the
current procedure returns to its caller, 1 level up the call stack. The
mechanism by which these options work is described in more detail below."
-options -form options -type dict -help\
"The value options must be a valid dictionary. The entries of that dictionary
are treated as additional option value pairs for the return command."
@values -form * -min 0 -max 1
result -form * -type string -optional 1
} "@doc -name Manpage: -url [manpage_tcl return]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::set
@cmd -name "Built-in: set"\
-summary\
"Read and write variables."\
-help\
"Returns the value of variable ${$I}varName${$NI}. If ${$I}value${$NI} is specified,
then set the value of ${$I}varName${$NI} to ${$I}value${$NI}, creating a new variable
if one does not already exist, and return its value. If ${$I}varName${$NI}
contains an open parenthesis and ends with a close parenthesis,
then it refers to an array element: the characters before the
first open parenthesis are the name of the array, and the
characters between the parentheses are the index within the array.
Otherwise ${$I}varName${$NI} refers to a scalar variable.
If ${$I}varName${$NI} includes namespace qualifiers (in the array name if it
refers to an array element), or if ${$I}varName${$NI} is unqualified (does
not include the names of any containing namespaces) but no
procedure is active, ${$I}varName${$NI} refers to a namespace variable
resolved according to the rules described under NAME RESOLUTION
in the namespace manual page.
If a procedure is active and ${$I}varName${$NI} is unqualified, then ${$I}varName${$NI}
refers to a parameter or local variable of the procedure, unless
${$I}varName${$NI} was declared to resolve differently through one of the
global, variable, or upvar commands.
"
@values -min 1 -max 2
varName -type string -help\
"name of scalar or array variable
scalar variable e.g myvar
array element e.g myarray(identifier.x)
namespaced scalar variable e.g ::ns1::myvar
namespaced array element e.g ::ns1::myarray(subelement)
Nested datastructures may be simulated with an array by using
some programmer chosen convention to seperate levels.
e.g set myarray(config,0) \"val1\"
set myarray(config,1) \"etc\"
set myarray(data,0) {a b c}
see the dict command for an alternative datastructure."
value -type any -optional 1
} "@doc -name Manpage: -url [manpage_tcl set]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::socket
@cmd -name "Built-in: socket"\
-summary\
"Open a TCP network connection."\
-help\
"This command opens a network socket and returns a channel identifier that
may be used in future invocations of commands like ${$B}read${$N}, ${$B}puts${$N} and ${$B}flush${$N}.
At present only the TCP network protocol is supported over IPv4 and IPv6;
future releases may include support for additional protocols. The ${$B}socket${$N}
command may be used to open either the client or server side of a
connection, depending on whether the ${$B}-server${$N} switch is specified.
Note that the default encoding for all sockets is the system encoding, as
returned by ${$B}encoding${$N} system. Most of the time, you will need to use chan
configure to alter this to something else, such as utf-8 (ideal for
communicating with other Tcl processes) or iso8859-1 (useful for many
network protocols, especially the older ones).
${$B}CLIENT SOCKETS${$N}
If the -server option is not specified, then the client side of a connection is opened
and the command returns a channel identifier that can be used for both reading and
writing. Port and host specify a port to connect to; there must be a server accepting
connections on this port. Port is an integer port number (or service name, where
supported and understood by the host operating system) and host is either a domain-style
name such as www.tcl.tk or a numerical IPv4 or IPv6 address such as 127.0.0.1 or
2001:DB8::1. Use localhost to refer to the host on which the command is invoked.
${$B}SERVER SOCKETS${$N}
If the -server option is specified then the new socket will be a server that listens on
the given port (either an integer or a service name, where supported and understood by
the host operating system; if port is zero, the operating system will allocate a free
port to the server socket which may be discovered by using chan configure to read the
-sockname option). If the host supports both, IPv4 and IPv6, the socket will listen on
both address families. Tcl will automatically accept connections to the given port. For
each connection Tcl will create a new channel that may be used to communicate with the
client. Tcl then invokes command (properly a command prefix list, see the EXAMPLES below)
with three additional arguments: the name of the new channel, the address, in network
address notation, of the client's host, and the client's port number.
Server channels cannot be used for input or output; their sole use is to accept new
client connections. The channels created for each incoming client connection are opened
for input and output. Closing the server channel shuts down the server so that no new
connections will be accepted; however, existing connections will be unaffected.
Server sockets depend on the Tcl event mechanism to find out when new connections are
opened. If the application does not enter the event loop, for example by invoking the
vwait command or calling the C procedure Tcl_DoOneEvent, then no connections will be
accepted.
If port is specified as zero, the operating system will allocate an unused port for use
as a server socket. The port number actually allocated may be retrieved from the created
server socket using the chan configure command to retrieve the -sockname option as
described below.
${$B}CONFIGURATION OPTIONS${$N}
The chan configure command can be used to query several readonly configuration options
for socket channels or in some cases to set alternative properties on socket channels:
-error
This option gets the current error status of the given socket. This is useful
when you need to determine if an asynchronous connect operation succeeded. If
there was an error, the error message is returned. If there was no error, an
empty string is returned.
Note that the error status is reset by the read operation; this mimics the
underlying getsockopt(SO_ERROR) call.
-sockname
For client sockets (including the channels that get created when a client
connects to a server socket) this option returns a list of three elements,
the address, the host name and the port number for the socket. If the host
name cannot be computed, the second element is identical to the address, the
first element of the list.
For server sockets this option returns a list of a multiple of three elements
each group of which have the same meaning as described above. The list contains
more than one group when the server socket was created without -myaddr or with
the argument to -myaddr being a domain name that resolves multiple IP addresses
that are local to the invoking host.
-peername
This option is not supported by server sockets. For client and accepted sockets,
this option returns a list of three elements; these are the address, the host name
and the port to which the peer socket is connected or bound. If the host name
cannot be computed, the second element of the list is identical to the address,
its first element.
-connecting
This option is not supported by server sockets. For client sockets, this option
returns 1 if an asynchronous connect is still in progress, 0 otherwise.
-keepalive
This option sets or queries the TCP keepalive option on the socket as 1 if
keepalive is turned on, 0 otherwise.
-nodelay
This option sets or queries the TCP nodelay option on the socket as 1 if nodelay
is turned on, 0 otherwise."
@form -form client
@leaders -min 0 -max 0
@opts
-myaddr -type string -typesynopsis ${$I}addr${$NI} -help\
"${$I}Addr${$NI} gives the domain-style name or numerical IP address of the client-side
network interface to use for the connection. This option may be useful if
the client machine has multiple network interfaces. If the option is omitted
then the client-side interface will be chosen by the system software."
-myport -type string -typesynopsis ${$I}port${$NI} -help\
"${$I}Port${$NI} specifies an integer port number (or service name, where supported and
understood by the host operating system) to use for the client's side of the
connection. If this option is omitted, the client's port number will be
chosen at random by the system software."
-async -type none -help\
"This option will cause the client socket to be connected asynchronously. This means
that the socket will be created immediately but may not yet be connected to the
server, when the call to ${$B}socket${$N} returns.
When a gets or flush is done on the socket before the connection attempt succeeds
or fails, if the socket is in blocking mode, the operation will wait until the
connection is completed or fails. If the socket is in nonblocking mode and a gets
or flush is done on the socket before the connection attempt succeeds or fails, the
operation returns immediately and fblocked on the socket returns 1. Synchronous
client sockets may be switched (after they have connected) to operating in
asynchronous mode using:
chan configure chan -blocking 0
See the ${$B}chan configure${$N} command for more details.
The Tcl event loop should be running while an asynchronous connection is in progress,
because it may have to do several connection attempts in the background. Running the
event loop also allows you to set up a writable channel event on the socket to get
notified when the asynchronous connection has succeeded or failed. See the vwait and
the chan commands for more details on the event loop and channel events.
The ${$B}chan configure${$N} option ${$B}-connecting${N} may be used to check if the connect is still
running. To verify a successful connect, the option ${$B}-error${N} may be checked when
${$B}-connecting${$N} returned 0.
Operation without the event queue requires at the moment calls to ${$B}chan configure${$N} to
advance the internal state machine."
@values -min 2 -max 2
host -type string
port -type string
@form -form server
@leaders -min 0 -max 0
@opts
-server -type list -typesynopsis ${$I}command${$NI}
-myaddr -type string -typesynopsis ${$I}addr${$NI} -help\
"Addr gives the domain-style name or numerical IP address of the server-side
network interface to use for the connection. This option may be useful if
the server machine has multiple network interfaces. If the option is
omitted then the server socket is bound to the wildcard address so that it
can accept connections from any interface. If addr is a domain name that
resolves to multiple IP addresses that are available on the local machine,
the socket will listen on all of them."
-reuseaddr -type boolean -help\
"Tells the kernel whether to reuse the local address if there is no socket
actively listening on it. This is the default on Windows."
-reuseport -type boolean -help\
"Tells the kernel whether to allow the binding of multiple sockets to the
same address and port."
@values -min 1 -max 1
port -type string -help\
"port number or service name"
} "@doc -name Manpage: -url [manpage_tcl socket]"\
{@examples -help {
Here is a very simple time server:
${[punk::args::moduledoc::tclcore::argdoc::example {
proc Server {startTime channel clientaddr clientport} {
puts "Connection from $clientaddr registered"
set now [clock seconds]
puts $channel [clock format $now]
puts $channel "[expr {$now - $startTime}] since start"
close $channel
}
socket -server [list Server [clock seconds]] 9900
vwait forever}]}
And here is the corresponding client to talk to the server and extract some information:
${[punk::args::moduledoc::tclcore::argdoc::example {
set server localhost
set sockChan [socket $server 9900]
gets $sockChan line1
gets $sockChan line2
close $sockChan
puts "The time on $server is $line1"
puts "That is [lindex $line2 0]s since the server started" }]}
}}
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::source
@cmd -name "Built-in: source"\
-summary\
"Evaluate a file or resource as a Tcl script."\
-help\
"This command takes the contents of the specified file or resource and passes
it to the Tcl interpreter as a text script. The return value from ${$B}source${$N} is the
return value of the last command executed in the script. If an error occurs in
evaluating the contents of the script then the ${$B}source${$N} command will return that
error. If a return command is invoked from within the script then the remainder
of the file will be skipped and the ${$B}source${$N} command will return normally with
the result from the return command.
The end-of-file character for files is \\32 (^Z) for all platforms. The source
command will read files up to this character. This restriction does not exist
for the read or gets commands, allowing for files containing code and data
segments (scripted documents). If you require a ^Z in code for string
comparison, you can use \\x1A, which will be safely substituted by the Tcl
interpreter into ^Z.
A leading BOM (Byte order mark) contained in the file is ignored for unicode
encodings (utf-8, utf-16, ucs-2).
The ${$B}-encoding${$N} option is used to specify the encoding of the data stored in
${$I}fileName${$NI}. When the ${$B}-encoding option${N} is omitted, the utf-8 encoding is assumed."
@leaders -min 0 -max 0
@opts
-encoding -type string -default utf-8 -typesynopsis ${$I}encodingName${$NI}
fileName
} "@doc -name Manpage: -url [manpage_tcl source]"\
{@examples -help {
Run the script in the file ${B}foo.tcl${$N} and then the script in ${$B}bar.tcl${$N}:
${[punk::args::moduledoc::tclcore::argdoc::example {
source foo.tcl
source bar.tcl }]}
Alternatively:
${[punk::args::moduledoc::tclcore::argdoc::example {
foreach scriptFile {foo.tcl bar.tcl} {
source $scriptFile
}}]}
}}
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::split
@cmd -name "Built-in: split"\
-summary\
"Split a string into a proper Tcl list."\
-help\
"Returns a list created by splitting string at each character that is in
the ${$I}splitChars${$NI} argument. Each element of the result list will
consist of the characters from ${$I}string${$NI} that lie between instances
of the characters in ${$I}splitChars${$NI}. Empty list elements will be
generated if string contains adjacent characters in ${$I}splitChars${$NI},
or if the first or last character of string is in ${$I}splitChars${$NI}.
If ${$I}splitChars${$NI} is an empty string then each character of ${$I}string${$NI}
becomes a separate element of the result list. ${$I}splitChars${$NI} defaults
to the standard white-space characters."
@values -min 1 -max 2
string -type string
splitChars -type string -optional 1
} "@doc -name Manpage: -url [manpage_tcl split]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
}
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
namespace eval argdoc {
punk::args::define {
@id -id ::tcl::string::cat
@cmd -name "Built-in: tcl::string::cat"\
-summary\
"Concatenate strings."\
-help\
"Concatenate the given strings just like placing them directly next to each other and
return the resulting compound string. If no strings are present, the result is an
empty string.
This primitive is occasionally handier than juxtaposition of strings when mixed quoting
is wanted, or when the aim is to return the result of a concatentation without resorting
to return -level 0, and is more efficient than building a list of arguments and using
join with an empty join string."
@values -min 0 -max -1
string -type string -optional 1 -multiple 1
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::define {
@id -id ::tcl::string::compare
@cmd -name "Built-in: tcl::string::compare" -help\
"Perform a character-by-character comparison of strings string1 and string2.
Returns -1, 0, or 1, dpending on whether string1 is lexicographically
lessthan, equal to, or greater than string2"
-nocase -type none -help\
"If -nocase is specified, then the strings are compared in a case insensitive manner."
-length -type integer -help\
"If -length is specified, then only the first length characters are used in the comparison.
If -length is negative, it is ignored."
@values -min 2 -max 2
string1 -type string
string2 -type string
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::define {
@id -id ::tcl::string::equal
@cmd -name "Built-in: tcl::string::equal"\
-summary\
"Compare strings."\
-help\
"Perform a character-by-character comparison of strings string1 and string2.
Returns 1 if string1 and string2 are identical, or 0 when not."
-nocase -type none -help\
"If -nocase is specified, then the strings are compared in a case insensitive manner."
-length -type integer -help\
"If -length is specified, then only the first length characters are used in the comparison.
If -length is negative, it is ignored."
@values -min 2 -max 2
string1 -type string
string2 -type string
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::define {
@id -id ::tcl::string::first
@cmd -name "Built-in: tcl::string::first" -help\
"Search ${$I}haystackString${$NI} for a sequence of characters that exactly match the characters
in ${$I}needleString${$NI}. If found, return the index of the first character in the first such
match within ${$I}haystackString${$NI}. If there is no match, then return -1. If startIndex is
specified (in any of the forms described in STRING_INDICES), then the search is
constrained to start with the character in ${$I}haystackString${$NI} specified by the index.
For Example,
${[punk::args::moduledoc::tclcore::argdoc::example {
string first a 0a23456789abcdef 5 }]}
will return ${$B}10${$N}, but
${[punk::args::moduledoc::tclcore::argdoc::example {
string first a 0a23456789abcdef 11 }]}
will return ${$B}-1${$N}.
"
@values -min 2 -max 3
needleString -type string
haystackString -type string
startIndex -type indexexpression -optional 1 -help\
"integer or simple expression."
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::define {
@id -id ::tcl::string::index
@cmd -name "Built-in: tcl::string::index" -help\
"Returns the ${$I}charIndex${$NI}'th character of the ${$I}string${$NI} argument. A ${$I}charIndex${$NI} of 0
corresponds to the first character of the string. ${$I}charIndex${$NI} may be specified
as described in the STRING INDICES section."
@values -min 2 -max 2
string -type string
charIndex -type indexexpression
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::define {
@id -id ::tcl::string::insert
@cmd -name "Built-in: tcl::string::insert" -help\
"Returns a copy of string with insertString inserted at the index'th character.
If index is start-relative, the first character inserted in the returned string will be
at the specified index.
If index is end-relative, the last character inserted in the returned string will be
at the specified index.
if index is at or before the start of string (e.g., index is 0), insertString is
prepended to the string.
If index is at or after the end of the string (e.g., index is end), insertString is
appended to string."
@values -min 3 -max 3
string -type string
index -type indexexpression -help\
"The index may be specified as described in the STRING_INDICES section"
insertString -type string
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::define {
@id -id ::tcl::string::last
@cmd -name "Built-in: tcl::string::last" -help\
"Search ${$I}haystackString${$NI} for a sequence of characters that exactly match the characters
in ${$I}needleString${$NI}. If found, return the index of the first character in the last such
match within ${$I}haystackString${$NI}. If there is no match, then return -1. If lastIndex is
specified (in any of the forms described in STRING_INDICES), then only the characters
in ${$I}haystackString${$NI} at or before the specified lastIndex will be considered by the search.
For example,
${[punk::args::moduledoc::tclcore::argdoc::example {
string last a 0a23456789abcdef 15 }]}
will return ${$B}10${$N}, but
${[punk::args::moduledoc::tclcore::argdoc::example {
string last a 0a23456789abcdef 9 }]}
will return ${$B}1${$N}."
@values -min 1 -max 3
needleString -type string
haystackString -type string
lastIndex -type indexexpression -optional 1 -help\
"integer or simple expression."
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::define {
@id -id ::tcl::string::length
@cmd -name "Built-in: tcl::string::length" -help\
"Returns a decimal string giving the number of characters in ${$I}string${$NI}. Note that this is
not necessarily the same as the number of bytes used to store the string. If the value
is a byte array value (such as those returned from reading a binary encoded channel),
then this will return the actual byte length of the value."
@values -min 1 -max 1
string -type string
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::define {
@id -id ::tcl::string::map
@cmd -name "Built-in: tcl::string::map" -help\
"Replaces substrings in string based on the key-value pairs in ${$I}mapping${$NI}. ${$I}mapping${$NI} is a
list of key value key value ... as in the form returned by ${$B}array get${$N}. Each instance
of a key in the string will be replaced with its corresponding value. If ${$B}-nocase${$N} is
specified, then matching is done without regard to case differences. Both key and
value may be multiple characters. Replacement is done in an ordered manner, so the
key appearing first in the list will be checked first, and so on. ${$I}string${$NI} is only
iterated over once, so earlier key replacements will have no affect for later key
matches. For example,
${[punk::args::moduledoc::tclcore::argdoc::example {
string map {abc 1 ab 2 a 3 1 0} 1abcaababcabababc }]}
will return the string ${$B}01321221${$N}.
Note that if an earlier key is a prefix of a later one, it will completely mask
the later one, So if the previous example were reordered like this,
${[punk::args::moduledoc::tclcore::argdoc::example {
string map {1 0 ab 2 a 3 abc 1} 1abcaababcabababc }]}
it will return the string ${$B}02c322c222c${$N}.
"
@opts
-nocase -type none
@values -min 2 -max 2
mapping -type dict
string -type string
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::define {
@id -id ::tcl::string::match
@cmd -name "Built-in: tcl::string::match" -help\
{See if pattern matches string; return 1 if it does, 0 if it does not. If -nocase is
specified, then the pattern attempts to match against the string in a case insensitive
manner. For the two strings to match, their contents must be identical except that the
following special sequences may appear in pattern:
${$B}*${$N}
Matches any sequence of characters in ${$I}string${$NI}, including a null string.
${$B}?${$N}
Matches any single character in ${$I}string${$NI}.
${$B}[${$N}chars${$B}]${$N}
Matches any character in the set given by chars. If a sequence of the form x-y
appears in chars, then any character between x and y, inclusive, will match. When
used with -nocase, the end points of the range are converted to lower case first.
Whereas {[A-z]} matches _ when matching case-sensitively (since _ falls between
the Z and a), with -nocase this is considered like {[A-Za-z]} (and probably what
was meant in the first place).
${$B}\${$N}x
Matches the single character ${$I}x${$NI}. This provides a way of avoiding the special
interpretation of the characters ${$B}*?[]\${$N} in ${$I}pattern${$NI}.}
@opts
-nocase -type none
@values -min 2 -max 2
pattern -type string
string -type string
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::define {
@id -id ::tcl::string::range
@cmd -name "Built-in: tcl::string::range" -help\
"Returns a range of consecutive characters from ${$I}string${$NI}, starting with the character whose
index is ${$I}first${$NI} and ending with the character whose index is ${$I}last${$NI} (using the forms described
in ${$B}STRING INDICES${$N}). An index of ${$B}0${$N} refers to the first character of the string; an index of
${$B}end${$N} refers to last character of the string. ${$I}first${$NI} and ${$I}last${$NI} may be specified as for the index
method. If ${$I}first${$NI} is less than zero then it is treated as if it were zero, and if ${$I}last${$NI} is
greater than or equal to the length of the string then it is treated as if it were ${$B}end${$N}. If
first is greater than last then an empty string is returned."
@values -min 3 -max 3
string -type string
first -type indexexpression
last -type indexexpression
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::define {
@id -id ::tcl::string::repeat
@cmd -name "Built-in: tcl::string::repeat"\
-summary\
"Build a string by repeating elements."\
-help\
"Returns a string consisting of string concatenated with itself count times."
@values -min 2 -max 2
string -type string
count -type int -help\
"If count is 0, the empty string will be returned."
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::define {
@id -id ::tcl::string::replace
@cmd -name "Built-in: tcl::string::replace" -help\
"Removes a range of consecutive characters from string, starting with the character whose
index is first and ending with the character whose index is last
(Using the forms described in STRING_INDICES). An index of 0 refers to the first
character of the string. First and last may be specified as for the index method.
If first is less than zero then it is treated as if it were zero, and if last is
greater than or equal to the length of the string then it is treated as if it were
end. The initial string is returned untouched, if first is greater than last, or if
first is equal to or greater than the length of the inital string, or last is less
than 0."
@values -min 3 -max 4
string -type string
first -type indexexpression
last -type indexexpression
newstring -type string -optional 1 -help\
"If newstring is specified, then it is placed in the removed character range."
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::define {
@id -id ::tcl::string::reverse
@cmd -name "Built-in: tcl::string::reverse" -help\
"Returns a string that is the same length as ${$I}string${$NI} but with its
characters in reverse order."
@values -min 1 -max 1
string -type string
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::define {
@id -id ::tcl::string::tolower
@cmd -name "Built-in: tcl::string::tolower" -help\
"Returns a value equal to ${$I}string${$NI} except that all upper (or title) case case letters have
been converted to lower case.
${$I}first${$NI} and ${$I}last${$NI} may be specified using the forms described in STRING INDICES."
@values -min 1 -max 3
string -type string
first -type indexexpression -optional 1 -help\
"If ${$I}first${$NI} is specified, it refers to the first char index in the string to start modifying.
If ${$I}last${$NI} is ${$B}not${$N} specified, only the character at position ${$I}first${$NI} is converted, otherwise ${$I}last${$NI} refers to
the char index in the string to stop at (inclusive)."
last -type indexexpression -optional 1 -help\
"If ${$I}last${$NI} is specified, it refers to the char index in the string to stop at (inclusive)."
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::define {
@id -id ::tcl::string::totitle
@cmd -name "Built-in: tcl::string::totitle" -help\
"Returns a value equal to string except that the first character in string is converted to
its Unicode title case variant (or upper case if there is no title case variant) and the
rest of the string is converted to lower case.
${$I}first${$NI} and ${$I}last${$NI} may be specified using the forms described in STRING INDICES."
@values -min 1 -max 3
string -type string
first -type indexexpression -optional 1 -help\
"If ${$I}first${$NI} is specified, it refers to the first char index in the string to start modifying.
If ${$I}last${$NI} is ${$B}not${$N} specified, only the character at position ${$I}first${$NI} is converted, otherwise ${$I}last${$NI} refers to
the char index in the string to stop at (inclusive)."
last -type indexexpression -optional 1 -help\
"If ${$I}last${$NI} is specified, it refers to the char index in the string to stop at (inclusive)."
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::define {
@id -id ::tcl::string::toupper
@cmd -name "Built-in: tcl::string::toupper" -help\
"Returns a value equal to ${$I}string${$NI} except that all lower (or title) case case letters have
been converted to upper case.
${$I}first${$NI} and ${$I}last${$NI} may be specified using the forms described in STRING INDICES."
@values -min 1 -max 3
string -type string
first -type indexexpression -optional 1 -help\
"If ${$I}first${$NI} is specified, it refers to the first char index in the string to start modifying.
If ${$I}last${$NI} is ${$B}not${$N} specified, only the character at position ${$I}first${$NI} is converted, otherwise ${$I}last${$NI} refers to
the char index in the string to stop at (inclusive)."
last -type indexexpression -optional 1 -help\
"If ${$I}last${$NI} is specified, it refers to the char index in the string to stop at (inclusive)."
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::define {
@id -id ::tcl::string::trim
@cmd -name "Built-in: tcl::string::trim" -help\
{Returns a value equal to ${$I}string${$NI} except that any leading or trailing characters
present in the string given by ${$I}chars${$NI} are removed. if ${$I}chars${$NI} is not specified
then white space is removed (any character for which ${$N}string is space${$N} returns 1, and "\0"}
@values -min 1 -max 2
string -type string
chars -type string -optional 1
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::define {
@id -id ::tcl::string::trimleft
@cmd -name "Built-in: tcl::string::trimleft" -help\
{Returns a value equal to ${$I}string${$NI} except that any leading characters
present in the string given by ${$I}chars${$NI} are removed. if ${$I}chars${$NI} is not specified
then white space is removed (any character for which ${$N}string is space${$N} returns 1, and "\0"}
@values -min 1 -max 2
string -type string
chars -type string -optional 1
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::define {
@id -id ::tcl::string::trimright
@cmd -name "Built-in: tcl::string::trimright" -help\
{Returns a value equal to ${$I}string${$NI} except that any trailing characters
present in the string given by ${$I}chars${$NI} are removed. if ${$I}chars${$NI} is not specified
then white space is removed (any character for which ${$N}string is space${$N} returns 1, and "\0"}
@values -min 1 -max 2
string -type string
chars -type string -optional 1
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::define {
@id -id ::tcl::string::wordend
@cmd -name "Built-in: tcl::string::wordend" -help\
"Returns the index of the character just after the last one in the word containing
character ${$I}charIndex${$NI} of ${$I}string${$NI}.
A word is considered to be any contiguous range of alphanumeric (Unicode letters or decimal digits)
or underscore (Unicode connector punctuation) characters, or any single character other than these."
@values -min 2 -max 2
string -type string
charIndex -type indexexpression -help\
"integer or simple expresssion.
e.g end
e.g end-1
e.g M+N"
} "@doc -name Manpage: -url [manpage_tcl string]"
punk::args::define {
@id -id ::tcl::string::wordstart
@cmd -name "Built-in: tcl::string::wordstart" -help\
"Returns the index of the first character in the word containing
character ${$I}charIndex${$NI} of ${$I}string${$NI}.
A word is considered to be any contiguous range of alphanumeric (Unicode letters or decimal digits)
or underscore (Unicode connector punctuation) characters, or any single character other than these.
"
@values -min 2 -max 2
string -type string
charIndex -type indexexpression -help\
"integer or simple expresssion.
e.g end
e.g end-1
e.g M+N"
} "@doc -name Manpage: -url [manpage_tcl string]"
}
punk::args::define [punk::args::lib::tstr -return string {
@id -id ::tcl::string::is
@cmd -name "Built-in: tcl::string::is" -help\
"Returns 1 if string is a valid member of the specified character class, otherwise returns 0.
"
@leaders -min 1 -max 1
class -type string\
-choices {
alnum
alpha
ascii
boolean
control
dict
digit
double
entier
false
graph
integer
list
lower
print
punct
space
true
upper
wideinteger
wordchar
xdigit
}\
-choicelabels {
alnum\
" Any Unicode alphabet
or digit character"
alpha\
" Any Unicode alphabet
character"
ascii\
" Any character with
a value less than \\u0080
(those that are in the
7-bit ascii range)"
boolean\
" Any of the forms allowed
for Tcl_GetBoolean"
control\
" Any Unicode control char"
dict\
" Any proper dict structure,
with optional surrounding
whitespace. In case of
improper dict structure, 0
is returned and the varname
will contain the index of
the \"element\" where the
dict parsing fails or -1 if
this cannot be determined."
digit\
" Any Unicode digit char.
Note that this includes
chars outside of the \[0-9\]
range."
double\
" Any of the forms allowed
for Tcl_GetDoubleFromObj.
${$A_WARN}With optional surrounding${$A_RST}
${$A_WARN}whitespace.${$A_RST}"
entier\
" Synonym for integer"
false\
" Any of the forms allowed
for Tcl_GetBoolean where the
value is false"
graph\
" Any Unicode printing char
except space."
integer\
" Any of the valid string
formats for an integer value
of arbitrary size in Tcl,
${$A_WARN}with optional surrounding${$A_RST}
${$A_WARN}whitespace${$A_RST}. The formats
accepted are exactly those
accepted by the C routine
Tcl_GetBignumFromObj."
list\
" Any proper list structure,
with optional surrounding
whitespace. In case of
improper list structure, 0
is returned and the varname
will contain the index of
the \"element\" where list
parsing fails, or -1 if
this cannot be determined"
lower\
" Any Unicode lower case
alphabet character"
print\
" Any Unicode printing
character, including space"
punct\
" Any Unicode punctuation
character."
space\
" Any Unicode whitespace
character, mongolian vowel
separator (U+180e),
zero width space (U+200b),
word joiner (U+2060) or
zero width no-break space
(U+feff) (=BOM)"
true\
" Any of the forms allowed
for Tcl_GetBoolean where the
value is true"
upper\
" Any upper case alphabet
character in the Unicode
character set"
wideinteger\
" Any of the valid forms
for a wide integer in Tcl,
${$A_WARN}with optional surrounding${$A_RST}
${$A_WARN}whitespace${$A_RST}. In case of
overflow in the value, 0 is
returned and the varname
will contain -1."
wordchar\
" Any Unicode word char.
That is any alphanumeric
character, and any
Unicode connector
punctuation characters
(e.g. underscore)"
xdigit\
" Any hexadecimal digit
character ([0-9A-Fa-f])."
}\
-help\
"character class
In the case of boolean, true and false, if the function will return 0, then the
varname will always be set to 0, due to the varied nature of a valid boolean value"
-strict -type none -help\
"If -strict is specified, then an empty string returns 0,
otherwise an empty string will return 1 on any class"
-failindex -type variablename -help\
"If -failindex is specified, then if the function returns 0,
the index in the string where the class was no longer
valid will be stored in the variable named."
@values -min 1 -max 1
string -type string -optional 0
}] "@doc -name Manpage: -url [manpage_tcl string]"
#a test of going deeper - we should be able to define these by reference to above text
#e.g dict get [lrange [punk::args::resolved_def -types leaders ::tcl::string::is class] 1 end] -choicelabels xdigit
#set string_class_choices [dict get [lrange [punk::args::resolved_def -types leaders ::tcl::string::is class] 1 end] -choices]
set string_class_choicelabels [dict get [lrange [punk::args::resolved_def -types leaders ::tcl::string::is class] 1 end] -choicelabels]
dict for {sclass slabel} $string_class_choicelabels {
punk::args::define [string map [list %sc% $sclass %slabel% $slabel] {
@id -id "::tcl::string::is %sc%"
@cmd -name "Built-in: string is %sc%" -help\
{%slabel%}
${[punk::args::resolved_def -types opts ::tcl::string::is -*]}
@values -min 1 -max 1
string -type string -optional 0
}] "@doc -name Manpage: -url [manpage_tcl string]"
}
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
namespace eval argdoc {
punk::args::define {
@id -id ::subst
@cmd -name "Built-in: subst"\
-summary\
"Perform backslash, command, and variable substitutions."\
-help\
"This command performs variable substitutions, command substitutions,
and backslash substitutions on its ${$I}string${$NI} argument and returns the
fully-substituted result. The substitutions are performed in exactly
the same way as for Tcl commands. As a result, the ${$I}string${$NI} argument is
actually substituted twice, once by the Tcl parser in the usual
fashion for Tcl commands, and again by the subst command.
If any of the ${$B}-nobackslashes${$N}, ${$B}-nocommands${$N}, or ${$B}-novariables${$N} are
specified, then the corresponding substitutions are not performed.
For example, if ${$B}-nocommands${$N} is specified, command substitution is not
performed: open and close brackets are treated as ordinary characters
with no special interpretation.
Note that the substitution of one kind can include substitution of
other kinds. For example, even when the ${$B}-novariables${$N} option is
specified, command substitution is performed without restriction.
This means that any variable substitution necessary to complete the
command substitution will still take place. Likewise, any command
substitution necessary to complete a variable substitution will take
place, even when ${$B}-nocommands${$N} is specified. See the EXAMPLES below.
If an error occurs during substitution, then ${$B}subst${$N} will return that
error. If a break exception occurs during command or variable
substitution, the result of the whole substitution will be the string
(as substituted) up to the start of the substitution that raised the
exception. If a continue exception occurs during the evaluation of a
command or variable substitution, an empty string will be substituted
for that entire command or variable substitution (as long as it is
well-formed Tcl.) If a return exception occurs, or any other return
code is returned during command or variable substitution, then the
returned value is substituted for that substitution.
See the EXAMPLES below. In this way, all exceptional return codes are
caught by ${$B}subst${$N}. The ${$B}subst${$N} command itself will either return an
error, or will complete successfully."
@opts
-nobackslashes -type none
-nocommands -type none
-novariables -type none
@values -min 1 -max -1
string -type string
} "@doc -name Manpage: -url [manpage_tcl subst]"
}
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
namespace eval argdoc {
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::switch
@cmd -name "Built-in: switch"\
-summary\
"Evaluate one of several scripts, depending on a given value."\
-help\
"The ${$B}switch${$N} command matches its ${$I}string${$NI} argument against each of the ${$I}pattern${$NI} arguments
in order. As soon as it finds a ${$I}pattern${$NI} that matches ${$I}string${$NI} it evaluates the following
${$I}body${$NI} argument by passing it recursively to the Tcl interpreter and returns the result
of that evaluation. If the last ${$I}pattern${$NI} argument is ${$B}default${$N} then it matches anything.
If no ${$I}pattern${$NI} argument matches ${$I}string${$NI} and no default is given, then the ${$B}switch${$N} command
returns an empty string.
If the initial arguments to ${$B}switch${$N} start with - then they are treated as options unless
there are exactly two arguments to ${$B}switch${$N} (in which case the first must the ${$I}string${$NI} and
the second must be the ${$I}pattern/body${$NI} list).
Two syntaxes are provided for the ${$I}pattern${$NI} and ${$I}body${$NI} arguments. The first uses a separate
argument for each of the patterns and commands; this form is convenient if substitutions
are desired on some of the patterns or commands. The second form places all of the
patterns and commands together into a single argument; the argument must have proper
list structure, with the elements of the list being the patterns and commands. The
second form makes it easy to construct multi-line switch commands, since the braces
around the whole list make it unnecessary to include a backslash at the end of each
line. Since the ${$I}pattern${$NI} arguments are in braces in the second form, no command or
variable substitutions are performed on them; this makes the behavior of the second form
different than the first form in some cases.
If a ${$I}body${$NI} is specified as - it means that the ${$I}body${$NI} for the next pattern should also be
used as the body for this pattern (if the next pattern also has a body of - then the
body after that is used, and so on). This feature makes it possible to share a single
${$I}body${$NI} among several patterns.
Beware of how you place comments in ${$B}switch${$N} commands. Comments should only be placed
${$B}inside${$N} the execution body of one of the patterns, and not intermingled with the
patterns."
@form -form separate
@form -form block
@leaders -form {separate block} -min 0 -max 0
@form -form {separate block}
@opts
-exact -type none -help\
"Use exact matching when comparing ${$I}string${$NI} to a pattern. This is the default."
-glob -type none -help\
"When matching ${$I}string${$NI} to the patterns, use glob-style matching (i.e. the same as
implemented by the ${$B}string match${$N} command)."
-regexp -type none -help\
"When matching ${$I}string${$NI} to the patterns, use regular expression matching (as described
in the ${$B}re_syntax${$N} reference page)."
-nocase -type none -help\
"Causes comparisons to be handled in a case-insensitive manner."
#matchvar/indexvar only legel when -regexp specified !todo
-matchvar -type string -typesynopsis ${$I}varName${$NI} -help\
"This option (only legal when ${$B}-regexp${$N} is also specified) specifies the name of a variable into
which the list of matches found by the regular expression engine will be written. The first
element of the list written will be the overall substring of the input string (i.e. the
string argument to ${$B}switch${$N}) matched, the second element of the list will be the substring
matched by the first capturing parenthesis in the regular expression that matched, and so on.
When a ${$B}default${$N} branch is taken, the variable will have the empty list written to it. This
option may be specified at the same time as the ${$B}-indexvar${$N} option."
-indexvar -type string -typesynopsis ${$I}varName${$NI} -help\
"This option (only legal when ${$B}-regexp${$N} is also specified) specifies the name of a variable into which the
list of indices referring to matching substrings found by the regular expression engine will be written.
The first element of the list written will be a two-element list specifying the index of the start and
index of the first character after the end of the overall substring of the input string (i.e. the string
argument to switch) matched, in a similar way to the ${$B}-indices${$N} option to ${$B}regexp${$N} can obtain. Similarly,
the second element of the list refers to the first capturing parenthesis in the regular expression that
matched, and so on. When a ${$B}default${$N} branch is taken, the variable will have the empty list written to it.
This option may be specified at the same time as the ${$B}-matchvar${$N} option."
-- -type none -help\
"Marks the end of options. The argument following this one will be treated as string even if it starts with a -.
This is not required when the matching patterns and bodies are grouped together in a single argument."
@values -form separate -min 3 -max -1
@values -form block -min 2 -max 2
string -form * -type string -help\
"string to match for."
"pattern body" -form separate -type {string script} -typesynopsis {${$I}pattern${$NI} ${$I}body${$NI}} -optional 0 -multiple 1
"{pattern body ?pattern body?...}" -form block -type dict
} "@doc -name Manpage: -url [manpage_tcl switch]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::tailcall
@cmd -name "Built-in: tailcall"\
-summary\
"Replace the current procedure with another command."\
-help\
"The ${$B}tailcall${$N} command replaces the currently executing procedure,
lambda aplication, or method with another command. The ${$I}command${$NI},
which will have ${$I}arg${$NI} ... passed as arguments if they are supplied,
will be looked up in the current namespace context, not in the caller's.
Apart from that difference in resolution, it is equivalent to:
------------------------------------------------
return [uplevel 1 [list ${$I}command ?${$I}arg${$NI} ...?]]
------------------------------------------------
This command may not be invoked from within an ${$I}uplevel${$NI} into a
procedure or insida a ${$B}catch${$N} inside a procedure or lambda."
@values -min 1 -max -1
command -type string
arg -optional 1 -multiple 1
} "@doc -name Manpage: -url [manpage_tcl tailcall]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::throw
@cmd -name "Built-in: throw"\
-summary\
"Generate a machine-readable error."\
-help\
"This command causes the current evaluation to be unwound with an error.
The error created is described by the type and message arguments: type must
contain a list of words describing the error in a form that is
machine-readable (and which will form the error-code part of the result
dictionary), and message should contain text that is intended for display to
a human being.
The stack will be unwound until the error is trapped by a suitable catch or
try command. If it reaches the event loop without being trapped, it will be
reported through the bgerror mechanism. If it reaches the top level of script
evaluation in tclsh, it will be printed on the console before, in the
non-interactive case, causing an exit (the behavior in other programs will
depend on the details of how Tcl is embedded and used).
By convention, the words in the type argument should go from most general to
most specific.
${B}EXAMPLES${$N}
The following produces an error that is identical to that produced by expr
when trying to divide a value by zero.
${[punk::args::moduledoc::tclcore::argdoc::example {
throw {ARITH DIVZERO {divide by zero}} {divide by zero}
}]}"
@values -min 2 -max 2
type -type list
message -type string
} "@doc -name Manpage: -url [manpage_tcl throw]"
}
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::trace
@cmd -name "Built-in: trace"\
-summary\
"Monitor variable accesses, command usages and command executions."\
-help\
"This command causes Tcl commands to be executed whenever certain
operations are invoked. "
#@form -synopsis "trace option ?arg arg...?"
@leaders -min 1 -max 1
option -choicegroups {
"" {add remove info}
obsolete {variable vdelete vinfo}
}\
-choiceinfo {
add {{doctype punkargs} {subhelp ::trace add}}
remove {{doctype punkargs} {subhelp ::trace remove}}
}
@values -unnamed true
} "@doc -name Manpage: -url [manpage_tcl trace]"
punk::args::define {
@id -id "::trace add"
@cmd -name "Built-in: trace add"\
-summary\
"Add a command, execution or variable trace."\
-help\
"Add a command, execution or variable trace."
@form -synopsis "trace add type name ops ?args?"
@leaders
type -choicegroups {
"" {command execution variable}
}\
-choiceinfo {
command {{doctype punkargs} {subhelp ::trace add command}}
execution {{doctype punkargs} {subhelp ::trace add execution}}
variable {{doctype punkargs}}
}
} "@doc -name Manpage: -url [manpage_tcl trace]"
punk::args::define {
@id -id "::trace add command"
@cmd -name "Built-in: trace add command"\
-summary\
"Add command trace for operation(s): rename delete"\
-help\
"Arrange for commandPrefix to be executed (with additional arguments)
whenever command name is modified in one of the ways given by the list
ops. Name will be resolved using the usual namespace resolution rules
used by commands. If the command does not exist, an error will be thrown."
name -type string -help\
"Name of command"
ops -type list -choices {rename delete} -choiceprefix 0 -choicemultiple {1 2}\
-choicelabels {
rename\
" Invoke commandPrefix whenever the traced command
is renamed. Note that renaming to the empty string
is considered deletion, and will not be traced with
'rename'"
delete\
" Invoke commandPrefix when the traced command is deleted.
Commands can be deleted explicitly using the rename command to
rename the command to an empty string. Commands are also deleted
when the interpreter is deleted, but traces will not be invoked
because there is no interpreter in which to execute them."
}\
-help\
"Indicates which operations are of interest."
commandPrefix -type string -help\
"When the trace triggers, depending on the operations being traced, a
number of arguments are appended to commandPrefix so that the actual
command is as follows:
--------------------------------
commandPrefix oldName newName op
--------------------------------
OldName and newName give the traced command's current (old) name,
and the name to which it is being renamed (the empty string if this
is a \"delete\" operation). Op indicates what operation is being
performed on the command, and is one of rename or delete as defined
above. The trace operation cannot be used to stop a command from being
deleted. Tcl will always remove the command once the trace is complete.
Recursive renaming or deleting will not cause further traces of the
same type to be evaluated, so a delete trace which itself deletes a
command, or a rename trace which itself renames the command will not
cause further trace evaluations to occur. Both oldName and newName are
fully qualified with any namespace(s) in which they appear.
"
} "@doc -name Manpage: -url [manpage_tcl trace]"
punk::args::define {
@id -id "::trace add variable"
@cmd -name "Built-in: trace add variable"\
-summary\
"Add variable trace for operation(s): array read write unset."\
-help\
"Arrange for commandPrefix to be executed whenever variable name is accessed
in one of the ways given by the list ops. Name may refer to a normal variable,
an element of an array, or to an array as a whole (i.e. name may be just the
name of an array, with no parenthesized index). If name refers to a whole
array, then commandPrefix is invoked whenever any element of the array is
manipulated. If the variable does not exist, it will be created but will not
be given a value, so it will be visible to namespace which queries, but not to
info exists queries."
name -type string -help\
"Name of variable"
# ---------------------------------------------------------------
ops -type list -choices {array read write unset} -choiceprefix 0\
-choicemultiple {1 4}\
-choicecolumns 1\
-choicelabels {
array\
" Invoke commandPrefix whenever the variable is accessed or
modified via the array command, provided that name is not a
scalar variable at the time that the array command is invoked.
If name is a scalar variable, the access via the array command
will not trigger the trace."
read\
" Invoke commandPrefix whenever the variable isread."
write\
" Invoke commandPrefix whenever the variable is written."
unset\
" Invoke commandPrefix whenever the variable is unset. Variables
can be unset explicitly with the unset command, or implicitly
when procedures return (all of their local variables are unset).
Variables are also unset when interpreters are deleted, but
traces will not be invoked because there is no interpreter in
which to execute them."
}\
-help\
"Indicates which operations are of interest."
commandPrefix -type string -help\
"When the trace triggers, three arguments are appended to commandPrefix
so that the actual command is as follows:
-----------------------------------------
commandPrefix name1 name2 op
-----------------------------------------
Name1 gives the name for the variable being accessed. This is not
necessarily the same as the name used in the trace add variable command:
the upvar command allows a procedure to reference a variable under a
different name. If the trace was originally set on an array or array
element, name2 provides which index into the array was affected. This
information is present even when name1 refers to a scalar, which may
happen if the upvar command was used to create a reference to a single
array element. If an entire array is being deleted and the trace was
registered on the overall array, rather than a single element, then
name1 gives the array name and name2 is an empty string. Op indicates
what operation is being performed on the variable, and is one of read,
write, or unset as defined above.
CommandPrefix executes in the same context as the code that invoked the
traced operation: if the variable was accessed as part of a Tcl procedure,
then commandPrefix will have access to the same local variables as code in
the procedure. This context may be different than the context in which the
trace was created. If commandPrefix invokes a procedure (which it normally
does) then the procedure will have to use upvar or uplevel if it wishes to
access the traced variable. Note also that name1 may not necessarily be
the same as the name used to set the trace on the variable; differences
can occur if the access is made through a variable defined with the upvar
command.
For read and write traces, commandPrefix can modify the variable to affect
the result of the traced operation. If commandPrefix modifies the value of
a variable during a read or write trace, then the new value will be
returned as the result of the traced operation. The return value from
commandPrefix is ignored except that if it returns an error of any sort
then the traced operation also returns an error with the same error message
returned by the trace command (this mechanism can be used to implement
read-only variables, for example). For write traces, commandPrefix is
invoked after the variable's value has been changed; it can write a new
value into the variable to override the original value specified in the
write operation. To implement read-only variables, commandPrefix will have
to restore the old value of the variable.
While commandPrefix is executing during a read or write trace, traces on
the variable are temporarily disabled. This means that reads and writes
invoked by commandPrefix will occur directly, without invoking
commandPrefix (or any other traces) again. However, if commandPrefix
unsets the variable then unset traces will be invoked.
When an unset trace is invoked, the variable has already been deleted: it
will appear to be undefined with no traces. If an unset occurs because of
a procedure return, then the trace will be invoked in the variable context
of the procedure being returned to: the stack frame of the returning
procedure will no longer exist. Traces are not disabled during unset
traces, so if an unset trace command creates a new trace and accesses the
variable, the trace will be invoked. Any errors in unset traces are ignored.
If there are multiple traces on a variable they are invoked in order of
creation, most-recent first. If one trace returns an error, then no further
traces are invoked for the variable. If an array element has a trace set,
and there is also a trace set on the array as a whole, the trace on the
overall array is invoked before the one on the element.
Once created, the trace remains in effect either until the trace is removed
with the trace remove variable command described below, until the variable
is unset, or until the interpreter is deleted. Unsetting an element of array
will remove any traces on that element, but will not remove traces on the
overall array.
This command returns an empty string."
} "@doc -name Manpage: -url [manpage_tcl trace]"
punk::args::define {
@id -id "::trace add execution"
@cmd -name "Built-in: trace add execution"\
-summary\
"Add execution trace for operation(s): enter leave enterstep leavestep."\
-help\
"Arrange for commandPrefix to be executed (with additional arguments)
whenever command name is executed, with traces occurring at the points
indicated by the list ops. Name will be resolved using the usual namespace
resolution ruls used by commands. If the command does not exist, and error
will be thrown"
name -type string -help\
"Name of command"
# ---------------------------------------------------------------
ops -type list -choices {enter leave enterstep leavestep} -choiceprefix 0\
-choicemultiple {1 4}\
-choicecolumns 2\
-choicelabels {
enter\
" Invoke commandPrefix whenever the command name is executed,
just before the actual execution takes place."
leave\
" Invoke commandPrefix whenever the command name is executed,
just after the actual execution takes place."
enterstep\
" Invoke commandPrefix for every Tcl command which is executed
from the start of the execution of the procedure name until
that procedure finishes. CommandPrefix is invoked just before
the actual execution of the Tcl command being reported takes
place. For example if we have
\"proc foo {} { puts \"hello\" }\", then an enterstep trace
would be invoked just before \"puts \"hello\"\" is executed.
Setting an enterstep trace on a command name that does not
refer to a procedure will not result in an error and is
simply ignored."
leavestep\
" Invoke commandPrefix for every Tcl command which is executed
from the start of the execution of the procedure name until
that procedure finishes. CommandPrefix is invoked just after
the actual execution of the Tcl command being reported takes
place. Setting a leavestep trace on a command name that does
not refer to a procedure will not result in an error and is
simply ignored."
}\
-help\
"Indicates which operations are of interest."
commandPrefix -type string -help\
"When the trace triggers, depending on the operation being traced, a
number of arguments are appended to commandPrefix so that the actual
command is as follows:
For enter and enterstep operations:
-------------------------------
commandPrefix command-string op
-------------------------------
Command-string give the complete current command being executed
(the traced command for a enter operation, an arbitrary command
for an enterstep operation), including all arguments in their
fully expanded form. Op indicates what operation is being performed
on the command execution, and is on of enter or enterstep as
defined above. The trace operation can be used to stop the command
from executing, by deleting the command in question. Of course when
the command is subsequently executed, an \"invalid command\" error
will occur.
For leave and leavestep operations:
-------------------------------------------
commandPrefix command-string code result op
-------------------------------------------
Command-string gives the complete current command being executed
(the traced command for a leave operation, an arbitrary command
for a leavestep operation), including all arguments in their
fully expanded form. Code give the result code of that execution,
and result the result string. Op indicates what operation is being
performed on the command execution and is one of leave or leavestep
as defined above.
Note that the creation of many enterstep or leavestep traces can
lead to unintuitive results, since the invoked commands from one
trace can themselves lead to further command invocations for other
traces.
CommandPrefix executes in the same context as the code that invoked
the traced operation: thus the commandPrefix, if invoked from a
procedure, will have access to the same local variables as code in the
procedure. This context may be different thatn the context in which
the trace was created. If commandPrefix invokes a procedure (which
it normally does) then the procedure will have to use upvar or uplevel
commands if it wishes to access the local variables of the code which
invoked the trace operation.
While commandPrefix is executing during an execution trace, traces on
name are temporarily disabled. This allows the commandPrefix to execute
name in its body without invoking any other traces again. If an error
occurs while executing the commandPrefix, then the command name as a
whole will return that same error.
When multiple traces are set on name, then for enter and enterstep
operations, the traced commands are invoked in the reverse order of how
the traces were originally created; and for leave and leavestep operations,
the traced commands are invoked in the original order of creation.
The behaviour of execution traces is currently undefined for a command name
imported into another namespace.
"
} "@doc -name Manpage: -url [manpage_tcl trace]"
punk::args::define {
@id -id "::trace remove"
@cmd -name "Built-in: trace remove"\
-summary\
"Remove a command, execution or variable trace."\
-help\
"Remove a command, execution or variable trace."
@form -synopsis "trace remove type name ops ?args?"
@leaders
type -choicegroups {
"" {command execution variable}
}\
-choiceinfo {
command {{doctype punkargs} {subhelp ::trace remove command}}
execution {{doctype punkargs} {subhelp ::trace remove execution}}
variable {{doctype punkargs} {subhelp ::trace remove variable}}
}
} "@doc -name Manpage: -url [manpage_tcl trace]"
punk::args::define {
@id -id "::trace remove command"
@cmd -name "Built-in: trace remove command" -help\
"If there is a trace set on command name with the operations and command
given by opList and commandPrefix, then the trace is removed, so that
commandPrefix will never again be invoked. Returns an empty string. If
name does not exist, the command will throw an error"
@values
name -type string -help\
"Name of command"
opList -type list -help\
"A list of one or more of the following items:
rename
delete"
commandPrefix
} "@doc -name Manpage: -url [manpage_tcl trace]"
punk::args::define {
@id -id "::trace remove execution"
@cmd -name "Built-in: trace remove execution" -help\
"If there is a trace set on command name with the operations and command
given by opList and commandPrefix, then the trace is removed, so that
commandPrefix will never again be invoked. Returns an empty string. If
name does not exist, the command will throw an error"
@values
name -type string -help\
"Name of command"
opList -type list -help\
"A list of one or more of the following items:
enter
leave
enterstep
leavestep"
commandPrefix
} "@doc -name Manpage: -url [manpage_tcl trace]"
punk::args::define {
@id -id "::trace remove variable"
@cmd -name "Built-in: trace remove variable" -help\
"If there is a trace set on command name with the operations and command
given by opList and commandPrefix, then the trace is removed, so that
commandPrefix will never again be invoked. Returns an empty string."
@values
name -type string -help\
"Name of command"
opList -type list -help\
"A list of one or more of the following items:
array
read
write
unset"
commandPrefix
} "@doc -name Manpage: -url [manpage_tcl trace]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
namespace eval argdoc {
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::try
@cmd -name "Built-in: try"\
-summary\
"Trap and process errors and exceptions"\
-help\
"This command executes the script body and, depending on what the outcome of
that script is (normal exit, error, or some other exceptional result), runs
a handler script to deal with the case. Once that has all happened, if the
finally clause is present, the script it includes will be run and the result
of the handler (or the body if no handler matched) is allowed to continue to
propagate. Note that the finally clause is processed even if an error occurs
and irrespective of which, if any, handler is used.
The handler clauses are each expressed as several words, and must have one of
the following forms:
${$B}on${$N} code variableList script
This clause matches if the evaluation of body completed with the exception
code ${$I}code${$NI}. The code may be expressed as an integer or one of
the following literal words: ok, error, return, break, or continue. Those
literals correspond to the integers 0 through 4 respectively.
${$B}trap${$N} pattern variableList script
This clause matches if the evaluation of body resulted in an error and the
prefix of the -errorcode from the interpreter's status dictionary is equal
to the pattern. The number of prefix words taken from the -errorcode is
equal to the list-length of pattern, and inter-word spaces are normalized
in both the -errorcode and pattern before comparison.
The variableList word in each handler is always interpreted as a list of
variable names. If the first word of the list is present and non-empty, it
names a variable into which the result of the evaluation of body (from the main
try) will be placed; this will contain the human-readable form of any errors.
If the second word of the list is present and non-empty, it names a variable
into which the options dictionary of the interpreter at the moment of
completion of execution of body will be placed.
The script word of each handler is also always interpreted the same: as a Tcl
script to evaluate if the clause is matched. If script is a literal - and the
handler is not the last one, the script of the following handler is invoked
instead (just like with the switch command).
Note that handler clauses are matched against in order, and that the first
matching one is always selected. At most one handler clause will selected. As a
consequence, an on error will mask any subsequent trap in the try. Also note
that on error is equivalent to trap {}.
If an exception (i.e. any non-ok result) occurs during the evaluation of either
the handler or the finally clause, the original exception's status dictionary
will be added to the new exception's status dictionary under the -during key."
@leaders -min 0 -max 0
@values -min 1 -max -1
body -type script
# handler for multiple on and/or trap clauses
#This works,but is not ideal. Does not extend to more complex cases.
#we would like to be able to define multiple handler clauses with possibly different arity,
#and display properly distinguished synopses and help (including for example -choices for code type)
#Each type of handler must be able to be interleaved arbitrarily.
#we can't define a separate on_handler and try_handler as it stands, because positionality would
#force all on_handlers to be together and all try_handlers to be together, and it would force
#one type of handler to be listed always before or always after the other.
handler -optional 1 -multiple 1 -type {literal(on)|literal(trap) string list string}\
-typesynopsis {"" code|pattern variableList script}
#todo?
#a way to define a compound type?
#handler -optional 1 -multiple 1 -type {<on_handler>|<try_handler>}
##<on_handler> -type {literal(on) <code> <variableList> <script>}
##<code> -type int -choices {0|ok 1|error 2|return 3|break 4|continue} -choicelabels {...}
#..
##<try_handler> -type {literal(trap) <pattern> <variableList> <script>}
##<pattern> -type list
#consider also RPN for compound type definitions
##<mytype1> -type {{int double OR}}
##<mytype2> -type {{stringstartswith a stringendswith z AND int OR}}
finally -optional 1 -optional 1 -type {literal(finally) script}
} "@doc -name Manpage: -url [manpage_tcl try]"\
{@examples -help {
Ensure that a file is closed no matter what:
${[punk::args::moduledoc::tclcore::argdoc::example {
set f [open /some/file/name a]
try {
puts $f "some message"
# ...
} finally {
close $f
}
}]}
Handle different reasons for a file to not be openable for reading:
${[punk::args::moduledoc::tclcore::argdoc::example {
try {
set f [open /some/file/name r]
} trap {POSIX EISDIR} {} {
puts "failed to open /some/file/name: it's a directory"
} trap {POSIX ENOENT} {} {
puts "failed to open /some/file/name: it doesn't exist"
}
}]}
Proc to read a file in utf-8 encoding and return its contents.
The file is closed in success and error case by the finally clause.
It is allowed to call return within the try block. Remark that with
tcl 9, the read command may also throw utf-8 conversion errors:
${[punk::args::moduledoc::tclcore::argdoc::example {
proc readfile {filename} {
set f [open $filename r]
try {
fconfigure $f -encoding utf-8 -profile strict
return [read $f]
} finally {
close $f
}
}
}]}
}
}
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::variable
@cmd -name "Built-in: variable"\
-summary\
"Create and initialise a namespace variable."\
-help\
"This command is normally used within a namespace eval command to create one
or more variables within a namespace. Each variable name is initialized with
value. The value for the last variable is optional.
If a variable name does not exist, it is created. In this case, if value is
specified, it is assigned to the newly created variable. If no value is
specified, the new variable is left undefined. If the variable already exists,
it is set to value if value is specified or left unchanged if no value is
given. Normally, name is unqualified (does not include the names of any
containing namespaces), and the variable is created in the current namespace.
If name includes any namespace qualifiers, the variable is created in the
specified namespace. If the variable is not defined, it will be visible to the
namespace which command, but not to the info exists command.
If the variable command is executed inside a Tcl procedure, it creates local
variables linked to the corresponding namespace variables (and therefore these
variables are listed by info vars.) In this way the variable command resembles
the global command, although the global command resolves variable names with
respect to the global namespace instead of the current namespace of the
procedure. If any values are given, they are used to modify the values of the
associated namespace variables. If a namespace variable does not exist, it is
created and optionally initialized.
A name argument cannot reference an element within an array. Instead, name
should reference the entire array, and the initialization value should be left
off. After the variable has been declared, elements within the array can be set
using ordinary set or array commands."
#@form -form "setvalues" -synopsis "variable ?name value...? ?name?"
@form -form "setvalues"
@values -min 0 -max -1
"name value" -type {string any} -optional 1 -multiple 1
name -type string -optional 1
#In this case - we don't want name_value to display - as this is only used for documenting a Built-in
#For the case where an @arggroups is used also for parsing - the help should display the synopsis form
#and also the name of the var in which it is placed.
# e.g
# ?{name value}...?
# (name_value)
#The second line giving an indication the resulting list of pairs can be accessed with something like:
# dict get $argd values name_value
#@arggroup -name name_value -min 1 -max 2 -optional 1 -multiple 1 -args {
# name
# value
# }
@form -form "declare"
@values -min 1 -max 1
name -optional 0
} "@doc -name Manpage: -url [manpage_tcl variable]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::vwait
@cmd -name "Built-in: ::vwait"\
-summary\
"Process events until a variable is written."\
-help\
"This command enters the Tcl event loop to process events, blocking the application
if no events are ready. It continues processing events until some event handler sets
the value of the global variable varName. Once varName has been set, the vwait
command will return as soon as the event handler that modified varName completes.
The varName argument is always interpreted as a variable name with respect to the
global namespace, but can refer to any namespace's variables if the fully-qualified
name is given.
In the second more complex command form options allow for finer control of the wait
operation and to deal with multiple event sources.
The result returned by vwait is for the simple form an empty string. If the -timeout
option is specified, the result is the number of milliseconds remaining when the wait
condition has been met, or -1 if the wait operation timed out.
If the -extended option is specified, the result is made up of a Tcl list with an
even number of elements. Odd elements take the values readable, timeleft, variable,
and writable. Even elements are the corresponding variable and channel names or the
remaining number of milliseconds. The list is ordered by the occurrences of the
event(s) with the exception of timeleft which always comes last.
In some cases the vwait command may not return immediately after varName et.al. is set.
This happens if the event handler that sets varName does not complete immediately. For
example, if an event handler sets varName and then itself calls vwait to wait for a
different variable, then it may not return for a long time. During this time the
top-level vwait is blocked waiting for the event handler to complete, so it cannot
return either. (See the NESTED VWAITS BY EXAMPLE below.)
To be clear, multiple vwait calls will nest and will not happen in parallel. The
outermost call to vwait will not return until all the inner ones do. It is recommended
that code should never nest vwait calls (by avoiding putting them in event callbacks)
but when that is not possible, care should be taken to add interlock variables to the
code to prevent all reentrant calls to vwait that are not strictly necessary. Be aware
that the synchronous modes of operation of some Tcl packages (e.g., http) use vwait
internally; if using the event loop, it is best to use the asynchronous callback-based
modes of operation of those packages where available."
@form -form basic
@leaders -min 0 -max 0
@opts -min 0 -max 0
@values -min 1 -max 1
varName -type string
@form -form complex
@leaders -min 0 -max 0
@opts
-all -type none -help\
"All conditions for the wait operation must be met to complete the wait operation.
Otherwise (the default) the first event completes the wait"
-extended -type none -help\
"An extended result in list form is returned, see above for explanation."
-nofileevents -type none -help\
"File events are not handled in the wait operation."
-noidleevents -type none -help\
"Idle handlers are not invoked during the wait operation."
-notimerevents -type none -help\
"Timer handlers are not serviced during the wait operation."
-nowindowevents -type none -help\
"Events of the windowing system are not handled during the wait operation."
-readable -type string -typesynopsis ${$I}channel${$NI} -help\
"${$I}Channel${$NI} must name a Tcl channel open for reading. If ${$I}channel${$NI} is or becomes
readable the wait operation completes."
-timeout -type integer -typesynopsis ${$I}milliseconds${$NI} -help\
"The wait operation is constrained to ${$I}milliseconds${$NI}."
-variable -type string -typesynopsis ${$I}varName${$NI} -help\
"${$I}VarName${$NI} must be the name of a global variable. Writing or unsetting this variable
completes the wait operation."
-writable -type string -typesynopsis ${$I}channel${$NI} -help\
"${$I}Channel${$NI} must name a Tcl channel open for writing. If ${$I}channel${$NI} is or becomes
writable the wait operation completes."
-- -type none -help\
"Marks the end of options. All following arguments are handled as variable names."
@values -min 0 -max -1
varName -type string -multiple 1 -optional 1
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl vwait]"\
{@examples -help {
Run the event-loop continually until some event calls exit. (You can use any variable not mentioned elsewhere,
but the name forever reminds you at a glance of the intent.)
${[punk::args::moduledoc::tclcore::argdoc::example {
vwait forever
}]}
Wait five seconds for a connection to a server socket, otherwise close the socket and continue running the script:
${[punk::args::moduledoc::tclcore::argdoc::example {
# Initialise the state
after 5000 set state timeout
set server [socket -server accept 12345]
proc accept {args} {
global state connectionInfo
set state accepted
set connectionInfo $args
}
# Wait for something to happen
vwait state
# Clean up events that could have happened
close $server
after cancel set state timeout
# Do something based on how the vwait finished...
switch $state {
timeout {
puts "no connection on port 12345"
}
accepted {
puts "connection: $connectionInfo"
puts [lindex $connectionInfo 0] "Hello there!"
}
}
}]}
A command that will wait for some time delay by waiting for a namespace variable to be set. Includes an interlock
to prevent nested waits.
${[punk::args::moduledoc::tclcore::argdoc::example {
namespace eval example {
variable v done
proc wait {delay} {
variable v
if {$v ne "waiting"} {
set v waiting
after $delay [namespace code {set v done}]
vwait [namespace which -variable v]
}
return $v
}
}
}]}
${$B}NESTED VWAITS BY EXAMPLE${$N}
This example demonstrates what can happen when the vwait command is nested. The script will never finish because
the waiting for the a variable never finishes; that vwait command is still waiting for a script scheduled with
after to complete, which just happens to be running an inner vwait (for b) even though the event that the outer
vwait was waiting for (the setting of a) has occurred.
${[punk::args::moduledoc::tclcore::argdoc::example {
after 500 {
puts "waiting for b"
vwait b
puts "b was set"
}
after 1000 {
puts "setting a"
set a 10
}
puts "waiting for a"
vwait a
puts "a was set"
puts "setting b"
set b 42
}]}
If you run the above code, you get this output:
${[punk::args::moduledoc::tclcore::argdoc::example {
waiting for a
waiting for b
setting a
}]}
The script will never print a was set until after it has printed b was set because of the nesting of vwait
commands, and yet b will not be set until after the outer vwait returns, so the script has deadlocked. The only
ways to avoid this are to either structure the overall program in continuation-passing style or to use coroutine
to make the continuations implicit. The first of these options would be written as:
${[punk::args::moduledoc::tclcore::argdoc::example {
after 500 {
puts "waiting for b"
trace add variable b write {apply {args {
global a b
trace remove variable ::b write \
[lrange [info level 0] 0 1]
puts "b was set"
set ::done ok
}}}
}
after 1000 {
puts "setting a"
set a 10
}
puts "waiting for a"
trace add variable a write {apply {args {
global a b
trace remove variable a write [lrange [info level 0] 0 1]
puts "a was set"
puts "setting b"
set b 42
}}}
vwait done
}]}
The second option, with coroutine and some helper procedures, is done like this:
${[punk::args::moduledoc::tclcore::argdoc::example {
# A coroutine-based wait-for-variable command
proc waitvar globalVar {
trace add variable ::$globalVar write \
[list apply {{v c args} {
trace remove variable $v write \
[lrange [info level 0] 0 3]
after 0 $c
}} ::$globalVar [info coroutine]]
yield
}
# A coroutine-based wait-for-some-time command
proc waittime ms {
after $ms [info coroutine]
yield
}
coroutine task-1 eval {
puts "waiting for a"
waitvar a
puts "a was set"
puts "setting b"
set b 42
}
coroutine task-2 eval {
waittime 500
puts "waiting for b"
waitvar b
puts "b was set"
set done ok
}
coroutine task-3 eval {
waittime 1000
puts "setting a"
set a 10
}
vwait done
}]}
}}
}
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
namespace eval argdoc {
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::unset
@cmd -name "Built-in: unset"\
-summary\
{Delete variables.}\
-help\
"This command removes one or more variables. Each name is a variable name,
specified in any of the ways acceptable to the ${$B}set${$N} command. If a ${$I}name${$NI} refers
to an element of an array then that element is removed without affecting the
rest of the array. If a name consists of an array name with no parenthesized
index, then the entire array is deleted. The ${$B}unset${$N} command returns an empty
string as result. If ${$B}-nocomplain${$N} is specified as the first argument, any
possible errors are suppressed. The option may not be abbreviated, in order
to disambiguate it from possible variable names. The option -- indicates the
end of the options, and should be used if you wish to remove a variable with
the same name as any of the options. If an error occurs during variable
deletion, any variables after the named one causing the error are not deleted.
An error can occur when the named variable does not exist, or the name refers
to an array element but the variable is a scalar, or the name refers to a
variable in a non-existent namespace."
@leaders -min 0 -max 0
@opts
-nocomplain -type none
-- -type none
@values -min 0 -max -1
name -type string -multiple 1 -optional 1
} "@doc -name Manpage: -url [manpage_tcl upvar]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::update
@cmd -name "Built-in: update"\
-summary\
{Process pending events and idle callbacks.}\
-help\
"This command is used to bring the application up to date by entering the
event loop repeatedly until all pending events (including idle callbacks)
have been processed.
If the idletasks keyword is specified as an argument to the command, then no
new events or errors are processed; only idle callbacks are invoked. This
causes operations that are normally deferred, such as display updates and
window layout calculations, to be performed immediately.
The update idletasks command is useful in scripts where changes have been
made to the application's state and you want those changes to appear on the
display immediately, rather than waiting for the script to complete. Most
display updates are performed as idle callbacks, so update idletasks will
cause them to run. However, there are some kinds of updates that only happen
in response to events, such as those triggered by window size changes; these
updates will not occur in update idletasks.
The update command with no options is useful in scripts where you are
performing a long-running computation but you still want the application to
respond to events such as user interactions; if you occasionally call update
then user input will be processed during the next call to update."
@leaders -min 0 -max 0
@opts
@values -min 0 -max 1
idletasks -type literalprefix(idletasks) -optional 1
} "@doc -name Manpage: -url [manpage_tcl update]"\
{@examples -help {
Run computations for about a second and then finish:
${[punk::args::moduledoc::tclcore::argdoc::example {
set x 1000
set done 0
after 1000 set done 1
while {!$done} {
# A very silly example!
set x [expr {log($x) ** 2.8}]
# Test to see if our time-limit has been hit. This would
# also give a chance for serving network sockets and, if
# the Tk package is loaded, updating a user interface.
update
}
}]}
}
}]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::uplevel
@cmd -name "Built-in: uplevel"\
-summary\
"Execute a script in a different stack frame."\
-help\
{All of the ${$I}arg${$NI} arguments are concatenated as if they had been passed to
${$B}concat${$N}; the result is then evaluated in the variable context indicated by
${$I}level${$NI}. ${$B}Uplevel${$N} returns the result of that evaluation.
If ${$I}level${$NI} is an integer then it gives a distance (up the procedure calling
stack) to move before executing the command. If ${$I}level${$NI} consists of ${$B}#${$N}
followed by an integer then the level gives an absolute level. If ${$I}level${$NI} is
omitted then it defaults to ${$B}1${$N}. ${$I}Level${$NI} cannot be defaulted if the first
command argument is an integer or starts with ${$B}#${$N}.
For example, suppose that procedure a was invoked from top-level, and that
it called b, and that b called c. Suppose that c invokes the uplevel
command. If level is 1 or #2 or omitted, then the command will be executed
in the variable context of b. If level is 2 or #1 then the command will be
executed in the variable context of a. If level is 3 or #0 then the command
will be executed at top-level (only global variables will be visible).
The uplevel command causes the invoking procedure to disappear from the
procedure calling stack while the command is being executed. In the above
example, suppose c invokes the command:
${[punk::args::moduledoc::tclcore::argdoc::example {
uplevel 1 {set x 43; d}}]}
where d is another Tcl procedure. The set command will modify the variable
x in b's context, and d will execute at level 3, as if called from b. If it
in turn executes the command:
${[punk::args::moduledoc::tclcore::argdoc::example {
uplevel 1 {set x 42}}]}
then the set command will modify the same variable x in b's context: the
procedure c does not appear to be on the call stack when d is executing.
The info level command may be used to obtain the level of the current
procedure.
${$B}Uplevel${$N} makes it possible to implement new control constructs as Tcl
procedures (for example, uplevel could be used to implement the while
construct as a Tcl procedure).
The ${$B}namespace eval${$N} and ${$B}apply${$N} commands offer other ways (besides procedure
calls) that the Tcl naming context can change. They add a call frame to the
stack to represent the namespace context. This means each ${$B}namespace eval${$N}
command counts as another call level for ${$B}uplevel${$N} and ${$B}upvar${$N} commands. For
example, ${$B}info level 1${$N} will return a list describing a command that is either
the outermost procedure call or the outermost ${$B}namespace eval${$N} command. Also,
${$B}uplevel #0${$N} evaluates a script at top-level in the outermost namespace (the
global namespace).}
@leaders -min 0 -max 1
level -type int|stringstartswith(#) -optional 1 -default 1
@values -min 1 -max -1
arg -type string -optional 0 -multiple 1
} "@doc -name Manpage: -url [manpage_tcl uplevel]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::upvar
@cmd -name "Built-in: upvar"\
-summary\
{Create link to variable in a different stack frame.}\
-help\
{This command arranges for one or more local variables in the current procedure
to refer to variables in an enclosing procedure call or to global variables.
Level may have any of the forms permitted for the ${$B}uplevel${$N} command, and may be
omitted (it defaults to 1). For each otherVar argument, upvar makes the
variable by that name in the procedure frame given by level (or at global level,
if level is #0) accessible in the current procedure by the name given in the
corresponding myVar argument. The variable named by otherVar need not exist at
the time of the call; it will be created the first time myVar is referenced,
just like an ordinary variable. There must not exist a variable by the name
myVar at the time upvar is invoked. MyVar is always treated as the name of a
variable, not an array element. An error is returned if the name looks like an
array element, such as ${$B}a(b)${$N}. OtherVar may refer to a scalar variable, an array,
or an array element. Upvar returns an empty string.
The upvar command simplifies the implementation of call-by-name procedure
calling and also makes it easier to build new control constructs as Tcl
procedures.
For example, consider the following procedure:
${[punk::args::moduledoc::tclcore::argdoc::example {
proc add2 name {
upvar $name x
set x [expr {$x + 2}]
}}]}
If add2 is invoked with an argument giving the name of a variable, it adds
two to the value of that variable. Although add2 could have been implemented
using ${$B}uplevel${$N} instead of ${$B}upvar${$N}, ${$B}upvar${$N} makes it simpler for add2 to access the
variable in the caller's procedure frame.
${$B}namespace eval${$N} is another way (besides procedure calls) that the Tcl naming
context can change. It adds a call frame to the stack to represent the namespace
context. This means each ${$B}namespace eval${$N} command counts as another call level for
${$B}uplevel${$N} and ${$B}upvar${$N} commands. For example, ${$B}info level 1${$N} will return a list
describing a command that is either the outermost procedure call or the outermost
${$B}namespace eval${$N} command. Also, ${$B}uplevel #0${$N} evaluates a script at top-level in the
outermost namespace (the global namespace).
If an upvar variable is unset (e.g. ${$B}x${$N} in ${$B}add2${$N} above), the ${$B}unset${$N} operation affects
the variable it is linked to, not the upvar variable. There is no way to unset an
upvar variable except by exiting the procedure in which it is defined. However, it
is possible to retarget an upvar variable by executing another ${$B}upvar${$N} command.}
@leaders -min 0 -max 1 -takewhenargsmodulo 2
#consider -takewhenargsmodulo 2 ?? incompatible with various mixed @opts/@values configurations
#level -type int|stringstartswith(#) -optional 1 -default 1
# stringregexp(^#[0-9]$)
# stringsuffix(xxx)
#this leader is greedy - i.e if the type matches it will take it.
#this is at odds with the way Tcl parses upvar args - it seems to look at the number of total args
#and will not assign a first value that passes int|stringstartswith(#) to 'level' if there is an even number of args in total
#e.g tcl will accept: upvar #1 blah #2 etc
#hence the need for -takewhenargsmodulo 2
level -type int|stringstartswith(#) -optional 1 -default 1
@values -min 2 -max -1
varmapping -type {string string} -typesynopsis {${$I}otherVar${$NI} ${$I}myVar${$NI}} -optional 0 -multiple 1
} "@doc -name Manpage: -url [manpage_tcl upvar]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
lappend PUNKARGS [list {
@id -id ::while
@cmd -name "Built-in: while"\
-summary\
{Execute script repeatedly as long as a condition is met.}\
-help\
{The ${$B}while${$N} command evaluates test as an expression (in the same way
that ${$B}expr${$N} evaluates its argument). The value of the expression must a proper
boolean value; if it is a true value then body is executed by passing it to
the Tcl interpreter. Once body has been executed then test is evaluated again,
and the process repeats until eventually test evaluates to a false boolean
value. ${$B}Continue${$N} commands may be executed inside body to terminate the current
iteration of the loop, and ${$B}break${$N} commands may be executed inside body to cause
immediate termination of the ${$B}while${$N} command. The ${$B}while${$N} command always returns
an empty string.
Note that ${$I}test${$NI} should almost always be enclosed in braces. If not, variable
substitutions will be made before the ${$B}while${$N} command starts executing, which
means that variable changes made by the loop body will not be considered in
the expression. This is likely to result in an infinite loop. If ${$I}test${$NI} is
enclosed in braces, variable substitutions are delayed until the expression is
evaluated (before each loop iteration), so changes in the variables will be
visible. For an example, try the following script with and without the braces
around ${$B}$x<10:${$N}
${[punk::args::moduledoc::tclcore::argdoc::example {
set x 0
while {$x<10} {
puts "x is $x"
incr x
}
}]}
}
@values -min 2 -max 2
test -type expr
body -type script -help\
"Tcl script"
} "@doc -name Manpage: -url [manpage_tcl while]" ]
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
}
namespace eval argdoc {
if {[catch {zlib::pkgconfig get zlibVersion} ZLIBVERSION]} {
set ZLIBVERSION "(unknown)"
}
#for pre tcl 9.1?
#zlib is an ensemble-*like* native command
#we can't use 'namespace ensemble configure' to query it
# 2025 - check repo - it's being updated to an ensemble
#define subcommand documentation first
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@dynamic
@id -id "::zlib adler32"
@cmd -name "Built-in: ::zlib adler32"\
-summary\
"Compute Adler-32 checksum."\
-help\
"Compute a checksum of binary string ${$I}string${$NI} using the Adler32
algorithm. If given, ${$I}initValue${$NI} is used to initialize the checksum engine.
"
@values -min 1 -max 2
string -type string
initValue -type string -optional 1
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl zlib]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@dynamic
@id -id "::zlib crc32"
@cmd -name Built-in: ::zlib crc32"\
-summary\
"Compute CRC-32 checksum."\
-help\
"Compute a checksum of binary string ${$I}string${$NI} using the CRC-32
algorithm. If given, ${$I}initValue${$NI} is used to initialize the checksum engine.
"
@values -min 1 -max 2
string -type string
initValue -type string -optional 1
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl zlib]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@dynamic
@id -id "::zlib compress"
@cmd -name "Built-in: ::zlib compress"\
-summary\
"Compress with zlib-format."\
-help\
"Returns the zlib-format compressed binary data of the binary string in ${$I}string${$NI}.
If present, ${$I}level${$NI} gives the compression level to use (from 0, which is
uncompressed, to 9, maximally compressed)."
@values -min 1 -max 2
string -type string
level -type integer -range {0 9} -optional 1
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl zlib]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@dynamic
@id -id "::zlib decompress"
@cmd -name "Built-in: ::zlib decompress"\
-summary\
"Decompress zlib-format."\
-help\
"Returns the uncompressed version of the raw compressed binary data in
${$I}string${$NI}. If present, ${$I}bufferSize${$NI} is a hint as to what size of buffer is to
be used to receive the data."
@values -min 1 -max 2
string -type string
bufferSize -type integer -optional 1
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl zlib]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id "::zlib deflate"
@cmd -name "Built-in: ::zlib deflate" -help\
"Returns the raw compressed binary data of the binary string in ${$I}string${$NI}.
If present, ${$I}level${$NI} gives the compression level to use (from 0, which is
uncompressed, to 9, maximally compressed)."
@values -min 1 -max 2
string -type string
level -type integer -range {0 9} -optional 1
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl zlib]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id "::zlib push"
@cmd -name "Built-in: ::zlib push"\
-summary\
"Push a compressing/decompressing transform onto a channel."\
-help\
"Pushes a compressing or decompressing transformation onto the channel
channel. The transformation can be removed again with chan pop. The mode
argument determines what type of transformation is pushed.
Both compressing and decompressing channel transformations add extra
configuration options that may be accessed through chan configure.
The options are:
-checksum checksum
This read-only option gets the current checksum for the uncompressed
data that the compression engine has seen so far. It is valid for both
compressing and decompressing transforms, but not for the raw inflate
and deflate formats. The compression algorithm depends on what format
is being produced or consumed.
-dictionary binData
This read-write options gets or sets the initial compression dictionary
to use when working with compressing or decompressing the data to be
binData. It is not valid for transformations that work with gzip-format
data, and should not normally be set on compressing transformations
other than at the point where the transformation is stacked. Note that
this cannot be used to get the current active compression dictionary
mid-stream, as that information is not exposed by the underlying library.
-flush type
This write-only operation flushes the current state of the compressor to
the underlying channel. It is only valid for compressing transformations.
The type must be either sync or full for a normal flush or an expensive
flush respectively. Flushing degrades the compression ratio, but makes it
easier for a decompressor to recover more of the file in the case of data
corruption.
-header dictionary
This read-only option, only valid for decompressing transforms that are
processing gzip-format data, returns the dictionary describing the header
read off the data stream.
-limit readaheadLimit
This read-write option is used by decompressing channels to control the
maximum number of bytes ahead to read from the underlying data source.
See below for more information."
@leaders -min 2 -max 2
# -- --- --- --- --- --- --- --- --- --- ---
mode -type string -choicecolumns 2 -choices {compress decompress deflate gunzip gzip inflate} -choicelabels {
compress\
"The transformation will be a compressing
transformation that produces zlib-format
data on channel, which must be writable."
decompress\
"The transformation will be a decompressing
transformation that reads zlib-format data
from channel, which must be readable."
deflate\
"The transformation will be a compressing
transformation that produces raw compressed
data on channel, which must be writable."
gunzip\
"The transformation will be a decompressing
transformation that reads gzip-format data
from channel, which must be readable."
gzip\
"The transformation will be a compressing
transformation that produces gzip-format
data on channel, which must be writable."
inflate\
"The transformation will be a decompressing
transformation that reads raw compressed
data from channel, which must be readable."
}
channel -type string
@opts
-dictionary -type dict -typesynopsis ${$I}binData${$NI} -help\
"Sets the compression dictionary to use when working with compressing or
decompressing the data to be binData. Not valid for transformations that
work with gzip-format data. The dictionary should consist of strings
(byte sequences) that are likely to be encountered later in the data to
be compressed, with the most commonly used strings preferably put towards
the end of the dictionary. Tcl provides no mechanism for choosing a good
such dictionary for a particular data sequence."
-header -type dict -typesynopsis ${$I}dictionary${$NI} -help\
"Passes a description of the gzip header to create, in the same format that
zlib gzip understands."
-level -type integer -range {0 9} -typesynopsis ${$I}compressionLevel${$NI} -help\
"How hard to compress the data. Must be an integer from 0 (uncompressed) to
9 (maximally compressed)."
-limit -type integer -typesynopsis ${$I}readaheadLimit${$NI} -help\
"The maximum number of bytes ahead to read when decompressing.
This option has become irrelevant. It was originally introduced to prevent
Tcl from reading beyond the end of a compressed stream in multi-stream
channels to ensure that the data after was left alone for further reading,
at the cost of speed.
Tcl now automatically returns any bytes it has read beyond the end of a
compressed stream back to the channel, making them appear as unread to
further readers."
@values -min 0 -max 0
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl zlib]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id "::zlib gunzip"
@cmd -name "Built-in: ::zlib gunzip"\
-summary\
"Decompress gzip format."\
-help\
"Return the uncompressed contents of binary string ${$I}string${$NI}, which must have
been in gzip format. If ${$B}-headerVar${$N} is given, store a dictionary describing
the contents of the gzip header in the variable called varName. The keys of the
dictionary that may be present are:
${$B}comment${$N}
The comment field from the header, if present.
${$B}crc${$N}
A boolean value describing whether a CRC of the header is computed.
${$B}filename${$N}
The filename field from the header, if present.
${$B}os${$N}
The operating system type code field from the header (if not the QW unknown value).
See RFC 1952 for the meaning of these codes.
${$B}size${$N}
The size of the uncompressed data.
${$B}time${$N}
The time field from the header if non-zero, expected to be time that the file named
by the ${$B}filename${$N} field was modified. Suitable for use with ${$B}clock format${$N}.
${$B}type${$N}
The type of the uncompressed data (${$B}binary${$N} or ${$B}text${$N}) if known."
@leaders -min 1 -max 1
string -type string
@opts
-headerVar -type string -typesynopsis ${$I}varName${$NI}
@values -max 0
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl zlib]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id "::zlib gzip"
@cmd -name "Built-in: ::zlib gzip"\
-summary\
"Compress with gzip format."\
-help\
"Return the compressed contents of binary string string in gzip format.
If -level is given, level gives the compression level to use (from 0,
which is uncompressed, to 9, maximally compressed). If -header is given,
dict is a dictionary containing values used for the gzip header.
The following keys may be defined:
${$B}comment${$N}
Add the given comment to the header of the gzip-format data.
${$B}crc${$N}
A boolean saying whether to compute a CRC of the header. Note that
if the data is to be interchanged with the gzip program, a header CRC
should not be computed.
${$B}filename${$N}
The name of the file that the data to be compressed came from.
${$B}os${$N}
The operating system type code, which should be one of the values
described in RFC 1952.
${$B}time${$N}
The time that the file named in the filename key was last modified.
This will be in the same as is returned by clock seconds or ${$B}file
mtime${$N}.
${$B}type${$N}
The type of the data being compressed, being ${$B}binary${$N} or ${$B}text${$N}."
@leaders -min 1 -max 1
string -type string
@opts
-level -type integer -range {0 9} -typesynopsis ${$I}level${$NI}
-header -type dict -typesynopsis ${$I}dict${$NI}
@values -max 0
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl zlib]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
set ZLIB_CHOICES [list compress decompress deflate gunzip gzip inflate push stream adler32 crc32]
#manual synopses for subcommands not yet defined
set ZLIB_CHOICELABELS [subst -novariables {
compress "zlib compress string ?level?"
decompress "zlib decompress string ?buffersize?"
deflate "zlib deflate string ?level?"
gunzip "zlib gunzip string ?-headerVar varName?"
gzip "zlib gzip string ?-level level? ?-header dict?"
inflate "zlib inflate string ?bufferSize?"
push "zlib push [punk::ansi::a+ italic]mode[punk::ansi::a+ noitalic] channel ?options ...?"
stream "zlib stream mode ?options?"
adler32 "zlib adler32 string ?initValue?"
crc32 "zlib crc32 string ?initValue?"
}]
set ZLIB_CHOICEINFO [dict create]
foreach sub $ZLIB_CHOICES {
#default for all
dict set ZLIB_CHOICEINFO $sub {{doctype native}}
}
foreach id [punk::args::get_ids "::zlib *"] {
if {[llength $id] == 2} {
lassign $id _ sub
dict set ZLIB_CHOICEINFO $sub {{doctype native} {doctype punkargs}}
#override manual synopsis entry
dict set ZLIB_CHOICELABELS $sub [punk::ns::synopsis "::zlib $sub"]
}
}
punk::args::define {
@id -id ::zlib
@cmd -name "Built-in: ::zlib"\
-summary\
"Zlib library compression and decompression operations."\
-help\
"zlib version: ${$ZLIBVERSION}
The zlib command provides access to the compression and check-summing facilities of the Zlib library
by Jean-loup Gailly and Mark Adler."
@leaders -min 1 -max 1
subcommand -type string\
-choicecolumns 2\
-choicegroups {
compression {compress decompress deflate gunzip gzip inflate}
channel {push}
streaming {stream}
checksumming {adler32 crc32}
}\
-choicelabels {${$ZLIB_CHOICELABELS}}\
-choiceinfo {${$ZLIB_CHOICEINFO}}
@values -unnamed true
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl zlib]"\
{@examples -help {
To compress a Tcl string, it should be first converted to a particular charset encoding since the zlib
command always operates on binary strings.
${[punk::args::moduledoc::tclcore::argdoc::example {
set binData [encoding convertto utf-8 $string]
set compData [zlib compress $binData]
}]}
When converting back, it is also important to reverse the charset encoding:
${[punk::args::moduledoc::tclcore::argdoc::example {
set binData [zlib decompress $compData]
set string [encoding convertfrom utf-8 $binData]
}]}
The compression operation from above can also be done with streams, which is especially helpful when you
want to accumulate the data by stages:
${[punk::args::moduledoc::tclcore::argdoc::example {
set strm [zlib stream compress]
$strm put [encoding convertto utf-8 $string]
# ...
$strm finalize
set compData [$strm get]
$strm close
}]}
}}
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
proc zipfs_subcommands {} {
dict set groups "" {canonical exists find info list mount mountdata root unmount}
dict set groups "ZIP Creation" {mkzip mkimg mkkey lmkimg lmkzip}
return [punk::args::ensemble_subcommands_definition -groupdict $groups -columns 2 zipfs]
}
set DYN_ZIPFS_SUBCOMMANDS {${[punk::args::moduledoc::tclcore::argdoc::zipfs_subcommands]}}
punk::args::define {
@dynamic
@id -id ::zipfs
@cmd -name "Built-in: ::zipfs"\
-summary\
"Mount and work with ZIP files within Tcl."\
-help\
"The ${$B}zipfs${$N} command provides Tcl with the ability to mount the contents of a
ZIP archive file as a virtual file system. Tcl's ZIP archive support is
limited to basic features and options. Supported storage methods include
only STORE and DEFLATE with optional simple encryption, sufficient to
prevent casual inspection of their contents but not able to prevent access
by even a moderately determined attacker. Strong encryption, multi-part
archives, platform metadata, zip64 formats and other compression methods
like bzip2 are not supported.
Files within mounted archives can be written to but new files or directories
cannot be created. Further, modifications to files are limited to the
mounted archive in memory and are not persisted to disk.
Paths in mounted archives are case-sensitive on all platforms."
@leaders -min 1 -max 1
${$DYN_ZIPFS_SUBCOMMANDS}
@values -unnamed true
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl zipfs]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::tcl::zipfs::canonical
@cmd -name "Built-in: ::zipfs::canonical" -help\
"This takes the name of a file, ${$I}filename${$NI}, and produces where it would be
mapped into a zipfs mount as its result. If specified, mountpoint says
within which mount the mapping will be done; if omitted, the main root of
the zipfs system is used."
@leaders -min 0 -max 0
@values -min 1 -max 1
mountpoint -type string -optional 1
filename -type string
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl zipfs]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::tcl::zipfs::exists
@cmd -name "Built-in: ::zipfs::exists" -help\
"Return 1 if the given filename exists in the mounted zipfs and 0 if it does not."
@leaders -min 0 -max 0
@values -min 1 -max 1
filename -type file
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl zipfs]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::tcl::zipfs::find
@cmd -name "Built-in: ::zipfs::find" -help\
"Returns the list of paths under directory ${$I}directoryName${$NI} which need not
be within a zipfs mounted archive. The paths are prefixed with
${$I}directoryName${$NI}. This command is also used by the ${$B}zipfs mkzip${$N} and
${$B}zipfs mkimg${$N} commands."
@leaders -min 0 -max 0
@values -min 1 -max 1
directoryName -type directory
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl zipfs]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::tcl::zipfs::info
@cmd -name "Built-in: ::zipfs::info" -help\
"Return information about the given ${$I}file${$NI} in the mounted zipfs.
The information consists of:
1. the name of the ZIP archive file that contains the file,
2. the size of the file after decompressions,
3. the compressed size of the file, and
4. the offset of the compressed data in the ZIP archive file.
As a special case, querying the mount point gives the start of the zip
data as the offset in (4), which can be used to truncate the zip
information from an executable. Querying an ancestor of a mount point
will raise an error."
@leaders -min 0 -max 0
@values -min 1 -max 1
file -type string
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl zipfs]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::tcl::zipfs::list
@cmd -name "Built-in: ::zipfs::list" -help\
"If pattern is not specified, the command returns a list of files across
all zipfs mounted archives. If pattern is specified, only those paths
matching the pattern are returned. By default, or with the -glob option,
the pattern is treated as a glob pattern and matching is done as described
for the string match command. Alternatively, the -regexp option may be
used to specify matching pattern as a regular expression. The file names
are returned in arbitrary order. Note that path separators are treated as
ordinary characters in the matching. Thus forward slashes should be used
as path separators in the pattern. The returned paths only include those
actually in the archive and does not include intermediate directories in
mount paths."
@leaders -min 0 -max 0
@values -min 1 -max 1
#patterntype -type literalprefix(-glob)|literalprefix(-regexp) -optional 1
patterntype -type string -default -glob -choices {-glob -regexp} -typesynopsis -glob|-regex
pattern -type string -optional 1
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl zipfs]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::tcl::zipfs::lmkimg
@cmd -name "Built-in: ::zipfs::lmkimg" -help\
"This command is like ${$B}zipfs mkimg${$N}, but instead of an input directory,
${$I}inlist${$NI} must be a Tcl list where the odd elements are the names of files
to be copied into the archive in the image, and the even elements are
their respective names within that archive."
@leaders -min 0 -max 0
@values -min 2 -max 4
outfile -type file
inlist -type dict
password -type any -optional 1
infile -type file -optional 1
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl zipfs]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::tcl::zipfs::lmkzip
@cmd -name "Built-in: ::zipfs::lmkzip" -help\
"This command is like ${$B}zipfs mkzip${$N}, but instead of an input directory,
${$I}inlist${$NI} must be a Tcl list where the odd elements are the names of files
to be copied into the archive, and the even elements are their respective
names within that archive."
@leaders -min 0 -max 0
@values -min 2 -max 3
outfile -type file
inlist -type dict
password -type any -optional 1
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl zipfs]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::tcl::zipfs::mount
@cmd -name "Built-in: ::zipfs::mount" -help\
"The ${$B}zipfs mount${$N} command mounts ZIP archives as Tcl virtual file systems
and returns information about current mounts.
With no arguments, the command returns a dictionary mapping mount points
to the path of the corresponding ZIP archive.
In the single argument form, the command returns the file path of the ZIP
archive mounted at the specified mount point.
In the third form, the command mounts the ZIP archive zipfile as a Tcl
virtual filesystem at ${$I}mountpoint${$NI}. After this command executes, files
contained in zipfile will appear to Tcl to be regular files at the mount
point. If ${$I}mountpoint${$NI} is specified as an empty string, it is defaulted to
the ${$B}[zipfs root]${$N}. The command returns the normalized mount point path.
If not under the zipfs file system root, ${$I}mountpoint${$NI} is normalized with
respect to it. For example, a mount point passed as either ${$B}mt${$N} or ${$B}/mt${$N} would
be normalized to ${$B}//zipfs:/mt${$N} (given that ${$B}zipfs root${$N} returns //zipfs:/).
An error is raised if the mount point includes a drive or UNC volume.
${$B}NB${$N}: because the current working directory is a concept maintained by the
operating system, using ${$B}cd${$N} into a mounted archive will only work in the
current process, and then not entirely consistently (e.g., if a shared
library uses direct access to the OS rather than through Tcl's filesystem
API, it will not see the current directory as being inside the mount and
will not be able to access the files inside the mount)."
@leaders -min 0 -max 0
@form -form dict
@values -min 0 -max 0
@form -form query
@values -min 1 -max 1
mountpoint
@form -form mount
@values -min 2 -max 3
zipfile -type file
mountpoint -type string
password -type string -optional 1
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl zipfs]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::tcl::zipfs::mountdata
@cmd -name "Built-in: ::zipfs::mountdata" -help\
"Mounts the ZIP archive content ${$I}data${$NI} as a Tcl virtual filesystem at ${$I}mountpoint${$NI}."
@leaders -min 0 -max 0
@values -min 1 -max 1
data -type any
mountpoint -type string
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl zipfs]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::tcl::zipfs::mkzip
@cmd -name "Built-in: ::zipfs::mkzip"\
-summary\
"Create a ZIP archive."\
-help\
"Creates a ZIP archive file named outfile from the contents of the input
directory indir (contained regular files only) with optional ZIP password
password. While processing the files below indir the optional file name
prefix given in strip is stripped off the beginning of the respective file
name if non-empty. When stripping, it is common to remove either the whole
source directory name or the name of its parent directory.
Caution: the choice of the indir parameter (less the optional stripped
prefix) determines the later root name of the archive's content."
@leaders -min 0 -max 0
@values -min 2 -max 4
outfile
indir
strip -type string -optional 1 -help\
"file name prefix"
password -type any -optional 1
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl zipfs]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::tcl::zipfs::mkimg
@cmd -name "Built-in: ::zipfs::mkimg" -help\
"Creates an image (potentially a new executable file) similar to ${$B}zipfs mkzip${$N};
see that command for a description of most parameters to this command, as
they behave identically here. If outfile exists, it will be silently
overwritten.
If the ${$I}infile${$NI} parameter is specified, this file is prepended in front of the
ZIP archive, otherwise the file returned by ${$B}info nameofexecutable${$N} (i.e., the
executable file of the running process, typically ${$B}wish${$N} or ${$B}tclsh${$N}) is used. If
the ${$I}password${$NI} parameter is not the empty string, an obfuscated version of that
password (see ${$B}zipfs mkkey${$N}) is placed between the image and ZIP chunks of the
output file and the contents of the ZIP chunk are protected with that
password. If the starting image has a ZIP archive already attached to it, it
is removed from the copy in ${$I}outfile${$NI} before the new ZIP archive is added.
If there is a file, main.tcl, in the root directory of the resulting archive
and the image file that the archive is attached to is a ${$B}tclsh${$N} (or ${$B}wish${$N})
instance (true by default, but depends on your configuration), then the
resulting image is an executable that will ${$B}source${$N} the script in that main.tcl
after mounting the ZIP archive, and will ${$B}exit${$N} once that script has been
executed.
Note: ${$B}tclsh${$N} and ${$B}wish${$N} can be built using either dynamic binding or static
binding of the core implementation libraries. With a dynamic binding, the
base application Tcl_Library contents are attached to the libtcl and libtk
shared library, respectively. With a static binding, the Tcl_Library contents,
etc., are attached to the application, tclsh or wish. When using ${$B}mkimg${$N} with a
statically built tclsh, it is the user's responsibility to preserve the
attached archive by first extracting it to a temporary location, and then add
whatever additional files desired, before creating and attaching the new
archive to the new application."
@leaders -min 0 -max 0
@values -min 2 -max 5
outfile
indir
strip -type string -optional 1 -help\
"file name prefix"
password -type string -optional 1
infile -type string -optional 1
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl zipfs]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::tcl::zipfs::mkkey
@cmd -name "Built-in: ::zipfs::mkzip" -help\
"Given the clear text ${$I}password${$NI} argument, an obfuscated string version is
returned with the same format used in the ${$B}zipfs mkimg${$N} command."
@leaders -min 0 -max 0
@values -min 1 -max 1
password -type string
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl zipfs]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::tcl::zipfs::root
@cmd -name "Built-in: ::zipfs::root" -help\
"Returns a constant string which indicates the mount point for zipfs
volumes for the current platform. User should not rely on the mount point
being the same constant string for all platforms."
@leaders -min 0 -max 0
@opts -min 0 -max 0
@values -min 0 -max 0
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl zipfs]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
punk::args::define {
@id -id ::tcl::zipfs::unmount
@cmd -name "Built-in: ::zipfs::unmount" -help\
"Unmounts a previously mounted ZIP archive mounted to ${$I}mountpoint${$NI}. The
command will fail with an error exception if there are any files within
the mounted archive are open."
@leaders -min 0 -max 0
@opts -min 0 -max 0
@values -min 1 -max 1
mountpoint
} "@doc -name Manpage: -url [punk::args::moduledoc::tclcore::manpage_tcl zipfs]"
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
}
# -- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
#*** !doctools
#[subsection {Namespace punk::args::moduledoc::tclcore}]
#[para] Core API functions for punk::args::moduledoc::tclcore
#[list_begin definitions]
#proc sample1 {p1 n args} {
# #*** !doctools
# #[call [fun sample1] [arg p1] [arg n] [opt {option value...}]]
# #[para]Description of sample1
# #[para] Arguments:
# # [list_begin arguments]
# # [arg_def tring p1] A description of string argument p1.
# # [arg_def integer n] A description of integer argument n.
# # [list_end]
# return "ok"
#}
#*** !doctools
#[list_end] [comment {--- end definitions namespace punk::args::moduledoc::tclcore ---}]
}
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# Secondary API namespace
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
tcl::namespace::eval punk::args::moduledoc::tclcore::lib {
tcl::namespace::export {[a-z]*} ;# Convention: export all lowercase
tcl::namespace::path [tcl::namespace::parent]
#*** !doctools
#[subsection {Namespace punk::args::moduledoc::tclcore::lib}]
#[para] Secondary functions that are part of the API
#[list_begin definitions]
#proc utility1 {p1 args} {
# #*** !doctools
# #[call lib::[fun utility1] [arg p1] [opt {?option value...?}]]
# #[para]Description of utility1
# return 1
#}
#*** !doctools
#[list_end] [comment {--- end definitions namespace punk::args::moduledoc::tclcore::lib ---}]
}
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
# ++ +++ +++ +++ +++ +++ +++ +++ +++ +++ +++
namespace eval ::punk::args::register {
#use fully qualified so 8.6 doesn't find existing var in global namespace
lappend ::punk::args::register::NAMESPACES ::punk::args::moduledoc::tclcore ::punk::args::moduledoc::tclcore::argdoc
}
## Ready
package provide punk::args::moduledoc::tclcore [tcl::namespace::eval punk::args::moduledoc::tclcore {
variable pkg punk::args::moduledoc::tclcore
variable version
set version 999999.0a1.0
}]
return
#*** !doctools
#[manpage_end]