SimpleProc v1.0
The Simple Development Library procedures with extended argument syntax
Project: the Simple Development Library.
::Simple::Argument::check-type args::Simple::Argument::information choices procedure argument::Simple::Argument::information default procedure argument::Simple::Argument::information defaultgiven procedure argument::Simple::Argument::information description procedure argument::Simple::Argument::information flaggiven flag::Simple::Argument::information givenflags::Simple::Argument::information isdefault argument::Simple::Argument::information type procedure argument::Simple::Proc::cget ?-checktype? ?-afterflags?::Simple::Proc::configure ?-checktype extbool? ?-afterflags integer?proc-ext ?-parseflags extbool? ?-checktype extbool? procedure arguments body::Simple::Proc::delete procedure::Simple::Proc::information access procedure::Simple::Proc::information alias procedure::Simple::Proc::information args procedure::Simple::Proc::information arguments procedure::Simple::Proc::information body procedure::Simple::Proc::information caller ?levels?::Simple::Proc::information checktype procedure::Simple::Proc::information exists procedure::Simple::Proc::information isextended procedure::Simple::Proc::information issubcommand procedure::Simple::Proc::information metadata procedure::Simple::Proc::information parseflags procedure::Simple::Proc::information runtimeparsing procedure::Simple::Proc::information subcommands command::Simple::Proc::information usage procedure::Simple::Proc::move sourceProcedure targetProcedure::Simple::Proc::resolve-alias procedure::Simple::Script::Header::add scriptName tag priority header::Simple::Script::Header::delete scriptName ?pattern?::Simple::Script::Header::get script ?pattern?::Simple::Script::Trailer::add scriptName tag priority trailer::Simple::Script::Trailer::delete scriptName ?pattern?::Simple::Script::Trailer::get script ?pattern?::Simple::Script::append scriptName scriptToAppend::Simple::Proc::NON-EXISTING-NAMESPACE::Simple::Proc::TYPE-CHECKING-AND-NO-PARSE-FLAGS::Simple::Proc::ARGS-MUST-BE-LAST::Simple::Proc::NON-OPT-AFTER-OPT::Simple::Proc::DEFAULT-NOT-ALLOWED::Simple::Proc::ARGS-NOT-ALLOWED::Simple::Proc::ARGS-LIST-OR-ANY::Simple::Proc::NO-FLAG-PARSING-AND-NO-FLAGS::Simple::Proc::NO-PARAM-FOR-FLAG::Simple::Proc::CANT-BETWEEN-SUBCO-AND-NO-SUBCO::Simple::Proc::NON-EXISTING-PROCEDURE::Simple::Proc::NON-EXISTING-ARGUMENT::Simple::Proc::NO-TYPE-CHOICE::Simple::Proc::CANT-BE-CALLED-FROM-TOPLEVEL::Simple::Script::DUPLICATED-TAG::Simple::Proc::VALUE-REQUIRED::Simple::Proc::ARRAY-NOT-ALLOWED::Simple::Proc::OPTIONAL-FLAG::Simple::Argument::check-type args::Simple::Argument::information choices procedure argument::Simple::Argument::information default procedure argument::Simple::Argument::information defaultgiven procedure argument::Simple::Argument::information description procedure argument::Simple::Argument::information flaggiven flag::Simple::Argument::information givenflags::Simple::Argument::information isdefault argument::Simple::Argument::information type procedure argument::Simple::Proc::cget ?-checktype? ?-afterflags?::Simple::Proc::configure ?-checktype extbool? ?-afterflags integer?proc-ext ?-parseflags extbool? ?-checktype extbool? procedure arguments body::Simple::Proc::delete procedure::Simple::Proc::information access procedure::Simple::Proc::information alias procedure::Simple::Proc::information args procedure::Simple::Proc::information arguments procedure::Simple::Proc::information body procedure::Simple::Proc::information caller ?levels?::Simple::Proc::information checktype procedure::Simple::Proc::information exists procedure::Simple::Proc::information isextended procedure::Simple::Proc::information issubcommand procedure::Simple::Proc::information metadata procedure::Simple::Proc::information parseflags procedure::Simple::Proc::information runtimeparsing procedure::Simple::Proc::information subcommands command::Simple::Proc::information usage procedure::Simple::Proc::move sourceProcedure targetProcedure::Simple::Proc::resolve-alias procedure::Simple::Script::Header::add scriptName tag priority header::Simple::Script::Header::delete scriptName ?pattern?::Simple::Script::Header::get script ?pattern?::Simple::Script::Trailer::add scriptName tag priority trailer::Simple::Script::Trailer::delete scriptName ?pattern?::Simple::Script::Trailer::get script ?pattern?::Simple::Script::append scriptName scriptToAppendSynopsis: the Simple Development Library procedures with extended argument syntax.
Keywords: procedure, extended, argument, type and flag.
This package provides a way to create procedures with extended argument syntax. This syntax includes argument types (with optional run-time type checking) and flag arguments with or without parameters which may be automatically parsed or left for the user to parse.
Procedures are provided to create, delete, rename and get information about procedures with extended argument syntax, as well as others to handle arguments in the body of those procedures, such as assess whether certain flag has been given in the command line or assess whether the value of a flag is that flag value.
This package also allows to handle headers and trailers for code scripts. Each header or trailer is identified by a tag and, within a script, headers and trailers are ordered by increasing priority. Procedures are provided to add, get and delete script headers and trailers.
Extended syntax procedures are created via the ::Simple::Proc::create procedure. The declaration specifies whether to perform run-time checking of the arguments types as well as whether to delegate the flag parsing to the user.
Extended argument syntax procedures can be deleted via ::Simple::Proc::delete or renamed via ::Simple::Proc::move. The ::Simple::Proc::information procedure provides several subcommands to query information about extended argument syntax procedures: issubcommand, subcommands, runtimeparsing, checktype, parseflags, exists, body, args, usage, arguments, type, default, choices, metadata and description.
The syntax of the extended arguments is similar to that of the arguments used by the opt package distributed with Tcl, so the upgrade for users using that should be easy; in fact this package was implemented as an evolution of the opt package for two reasons: 1) opt is slow and 2) it was deprecated from Tcl 8.1 (made private, actually).
This argument syntax is of the form {name type ?value? description}. There, "name" is the argument name, "type" its type, "value" its default value or choice list and "description" a string describing the argument. Types used by opt are of the form "-float", while The Simple Development Library removes the hyphen to yield "float"; further, some opt types are abbreviated (such as "int") while The Simple Development Library uses mostly unabbreviated names such as "integer". See the SimpleType package for further information about types. Extended arguments are further described in the proc-ext procedure.
The presence or absence of a regular flag in an extended procedure call argument list can be obtained via the ::Simple::Argument::information flaggiven procedure, while the complete list of all given flags is returned by ::Simple::Argument::information givenflags. For flags or optional arguments, ::Simple::Argument::information isdefault returns whether an extended procedure argument actual value matches its corresponding default value. Other subcommands of the ::Simple::Argument::information command are <description>, defaultgiven, default, type and choices.
This package encompasses the funcionality provided by the SimpleSubcommand package, so it is recommended not to directly use the later if using the former. In fact, all procedures provided by this package work for regular procedures also, so this is the only package needed to handle regular or extended argument syntax procedures as well as regular or subcommand procedures. Nevertheless, see the SimpleDeclare package declare-proc command, which encompasses proc-ext in turn.
The ::Simple::Proc::convert pair of procedures convert between extended and Tcl canonical procedure argument formats.
::Simple::Script::append allows to append scripts. The ::Simple::Script::Header::add and ::Simple::Script::Trailer::add procedures prepend a header or append a trailer to a script, respectively. Headers and trailers can be got or deleted with the ::Simple::Script::Header::get, ::Simple::Script::Trailer::get, ::Simple::Script::Header::delete and ::Simple::Script::Trailer::delete procedures.
# Install the package
package require SimplePackage
::Simple::Package::require-and-install SimpleProc
# Configure The Simple Development Library to store the metadata
::Simple::configure -storemetadata true
# Enable arguments run-time type checking
::Simple::Proc::configure -checktype true
# Create a procedure which takes an
# optional flag and a required integer
proc-ext {
   zero
} {
   {-zero             boolflag       {Zero flag}}
   { integer          integer        {Integer}}
} {
   if {$zero} {
      puts 0
   } else {
      puts $integer
   }
}
# Get some info about the procedure
# This displays the following:
#   |0
#   |?-zero? integer
#   |Zero flag
puts [::Simple::Proc::information issubcommand zero]
puts [::Simple::Proc::information usage zero]
puts [::Simple::Argument::information description zero -zero]
# Valid calls
# This displays the following:
#   |23
#   |0
#   |0
zero 23
zero 0
zero -zero 23
# Invalid call
# This displays the following:
#   |invalid value "foo" for argument "integer" of type "integer"
catch {zero foo} result
puts $result
# Create a couple of subcommand procedures
proc-ext {
   command foo
} {
   { integer          integer        {Integer}}
   { choice           choice {1 2}   {Choices}}
} {
   if {$integer > $choice} {
      puts {The integer is greater than the choice}
   } else {
      puts {The integer is lower or equal than the choice}
   }
}
proc-ext {
   command bar
} {
   {?integer?         integer 1      {Integer}}
} {
   if {[::Simple::Argument::information isdefault integer]} {
      puts {Default value}
   } else {
      puts {Non-default value}
   }
}
# This displays the following:
#   |The integer is lower or equal than the choice
#   |The integer is greater than the choice
#   |Default value
#   |Non-default value
command foo 1 2
command foo 8 1
command bar
command bar 8
# Get some info about the subcommand
# This displays the following:
#   |1
#   |foo bar
puts [::Simple::Proc::information issubcommand command]
puts [::Simple::Proc::information subcommands command]
# Delete one of the subcommands
::Simple::Proc::delete {command bar}
# Get some info about the subcommand
# This displays the following:
#   |foo
puts [::Simple::Proc::information subcommands command]
| Date | Reason | 
| 19-feb-1999 | Unreleased first version 0.1 | 
| 23-apr-2000 | First public release, version 0.2 | 
| 10-sep-2001 | Second public release, version 0.4 | 
| 17-feb-2003 | Third public release, version 0.5 | 
| 30-mar-2003 | Extra package, version 0.5.1 | 
| 24-oct-2004 | Copy functionality deleted, version 0.5.2 | 
| 03-dec-2004 | SimpleRegProc functionality moved here and changes to ::Simple::Proc::information subcommands, version 0.5.3 | 
| 11-may-2005 | Bug 11 correction, version 0.5.4 | 
| 22-jun-2005 | The Simple Development Library version 1.0 | 
Copyright (C) 1999-2005, Juan C. Gil (jgil@gmv.es).
Paradigm: procedural.
Requisites: SimpleVariable 1.0.
Description: extended format argument as {name type ?value? description}.
Description: canonical argument as {name ?value?}.
Type: boolean.
Value: 0.
Description: whether argument run-time type checking is performed for procedures created via the ::Simple::Proc::create procedure in order to check whether the actual arguments match their type. This has a performance penalty which should be considered. Notice that only those procedures created via the ::Simple::Proc::create procedure after modifying this option are affected by the change.
Type: integer.
Value: 5.
Description: if the number of arguments after the last flag in procedures created via the ::Simple::Proc::create procedure exceedes the value of this package option, those arguments are handled via an auxiliary "after flags" procedure. The optimum value of this parameter depends on the Tcl version used. The Simple Development Library default value corresponds to the latest Tcl version. Notice that only those procedures created via the ::Simple::Proc::create procedure after modifying this option are affected by the change.
::Simple::Proc
::Simple::Proc::Priv
::Simple::Argument
::Simple::Script
::Simple::Script::Header
::Simple::Script::Trailer
::Simple::Script::Priv
::Simple::Argument::check-type argsSynopsis: perform runtime type checking on named arguments.
Details: see section 4.1.
::Simple::Argument::information choices procedure argumentSynopsis: returns an extended procedure argument choices list.
Details: see section 4.2.
::Simple::Argument::information default procedure argumentSynopsis: returns a procedure argument default value.
Details: see section 4.3.
::Simple::Argument::information defaultgiven procedure argumentSynopsis: returns whether a procedure argument has a default value.
Details: see section 4.4.
::Simple::Argument::information description procedure argumentSynopsis: returns an extended procedure argument description.
Details: see section 4.5.
::Simple::Argument::information flaggiven flagSynopsis: returns whether a flag was given in an extended procedure call.
Details: see section 4.6.
::Simple::Argument::information givenflagsSynopsis: returns the flags and their parameters in an extended procedure call.
Details: see section 4.7.
::Simple::Argument::information isdefault argumentSynopsis: returns whether an argument value is the default one.
Details: see section 4.8.
::Simple::Argument::information type procedure argumentSynopsis: returns an extended procedure argument type.
Details: see section 4.9.
::Simple::Proc::cget ?-checktype? ?-afterflags?Synopsis: gets the package options.
Details: see section 4.10.
::Simple::Proc::configure ?-checktype extbool? ?-afterflags integer?Synopsis: configures the package options.
Details: see section 4.11.
proc-ext ?-parseflags extbool? ?-checktype extbool? procedure arguments bodySynopsis: creates a procedure with extended argument syntax.
Details: see section 4.12.
::Simple::Proc::delete procedureSynopsis: deletes a procedure.
Details: see section 4.13.
::Simple::Proc::information access procedureSynopsis: returns a declared procedure access mode.
Details: see section 4.14.
::Simple::Proc::information alias procedureSynopsis: returns a declared procedure alias.
Details: see section 4.15.
::Simple::Proc::information args procedureSynopsis: returns a procedure argument names list.
Details: see section 4.16.
::Simple::Proc::information arguments procedureSynopsis: returns a procedure argument list.
Details: see section 4.17.
::Simple::Proc::information body procedureSynopsis: returns a procedure body.
Details: see section 4.18.
::Simple::Proc::information caller ?levels?Synopsis: returns the caller procedure name.
Details: see section 4.19.
::Simple::Proc::information checktype procedureSynopsis: returns whether a procedure performs argument type checking.
Details: see section 4.20.
::Simple::Proc::information exists procedureSynopsis: returns whether a procedure exists.
Details: see section 4.21.
::Simple::Proc::information isextended procedureSynopsis: returns whether a procedure is an extended procedure.
Details: see section 4.22.
::Simple::Proc::information issubcommand procedureSynopsis: returns whether a procedure is a base command procedure.
Details: see section 4.23.
::Simple::Proc::information metadata procedureSynopsis: returns a declared procedure metadata.
Details: see section 4.24.
::Simple::Proc::information parseflags procedureSynopsis: returns whether a procedure has flag parsing enabled.
Details: see section 4.25.
::Simple::Proc::information runtimeparsing procedureSynopsis: returns whether a procedure run-time parses its arguments.
Details: see section 4.26.
::Simple::Proc::information subcommands commandSynopsis: returns a base command procedure subcommand list.
Details: see section 4.27.
::Simple::Proc::information usage procedureSynopsis: returns a procedure argument usage string.
Details: see section 4.28.
::Simple::Proc::move sourceProcedure targetProcedureSynopsis: renames a procedure.
Details: see section 4.29.
::Simple::Proc::resolve-alias procedureSynopsis: resolves command aliases.
Details: see section 4.30.
::Simple::Script::Header::add scriptName tag priority headerSynopsis: prepends a header to a script.
Details: see section 4.31.
::Simple::Script::Header::delete scriptName ?pattern?Synopsis: deletes headers from a script.
Details: see section 4.32.
::Simple::Script::Header::get script ?pattern?Synopsis: gets headers from a script.
Details: see section 4.33.
::Simple::Script::Trailer::add scriptName tag priority trailerSynopsis: appends a trailer to a script.
Details: see section 4.34.
::Simple::Script::Trailer::delete scriptName ?pattern?Synopsis: deletes trailers from a script.
Details: see section 4.35.
::Simple::Script::Trailer::get script ?pattern?Synopsis: gets trailers from a script.
Details: see section 4.36.
::Simple::Script::append scriptName scriptToAppendSynopsis: appends a non-empty script to another one.
Details: see section 4.37.
::Simple::Proc::NON-EXISTING-NAMESPACEMessage: can't create procedure "procedure": unknown namespace.
Explanation: the extended procedure procedure could not be created because the namespace does not exist.
Corrective action: use namespace eval to create the namespace.
::Simple::Proc::TYPE-CHECKING-AND-NO-PARSE-FLAGSMessage: can not have "-parseflags false" and argument run-time type checking.
Explanation: a procedure declaration failed because argument run-time type checking was enabled and flag parsing disabled.
Corrective action: either disable argument run-time type checking or enable flag parsing.
::Simple::Proc::ARGS-MUST-BE-LASTMessage: "args" must be the last argument.
Explanation: a procedure declaration failed because an argument named "args" was supplied not the last in the list.
::Simple::Proc::NON-OPT-AFTER-OPTMessage: non-optional argument "argument" after at least one optional argument.
Explanation: a procedure declaration failed because the non-optional argument argument was supplied after an optional argument.
Corrective action: all arguments following an optional one must be either explicitly optional or the special argument "args" which is implictly optional.
::Simple::Proc::DEFAULT-NOT-ALLOWEDMessage: can not have a default value for option or argument "option or argument name" of type "type".
Explanation: a procedure or option declaration failed because a default value was supplied for an option or argument which can not have it.
Corrective action: default values must be supplied for procedure optional arguments and for flags or options whose type is not "boolflag", and only for those.
::Simple::Proc::ARGS-NOT-ALLOWEDMessage: "args" is not allowed if flag parsing is disabled.
Explanation: a procedure declaration failed because an argument named "args" was supplied but flag parsing is disabled.
Corrective action: either remove the "args" argument or enable flags parsing.
::Simple::Proc::ARGS-LIST-OR-ANYMessage: "args" must be of type "list" or "any".
Explanation: a procedure declaration failed because an argument named "args" was supplied with a type other than "list" or "any".
::Simple::Proc::NO-FLAG-PARSING-AND-NO-FLAGSMessage: flag parsing disabled but no flags given.
Explanation: a procedure declaration failed because flag parsing was diabled but no flags were given in the argument list.
Corrective action: enable flag parsing.
::Simple::Proc::NO-PARAM-FOR-FLAGMessage: no parameter given for flag "flag" to "procedure".
Explanation: a call to the procedure procedure failed because no parameter was supplied for the flag flag.
Corrective action: supply a parameter for the flag.
::Simple::Proc::CANT-BETWEEN-SUBCO-AND-NO-SUBCOMessage: can't copy or rename [non-]subcommand "name 1" to [non-]subcommand "name 2".
Explanation: it is not allowed to copy or rename a non-subcommand to a subcommand or viceversa.
::Simple::Proc::NON-EXISTING-PROCEDUREMessage: "procedure" isn't a procedure, an extended procedure or a declared procedure.
Explanation: procedure is not a procedure, an extended procedure or a declared procedure.
Corrective action: provide a valid procedure name.
::Simple::Proc::NON-EXISTING-ARGUMENTMessage: procedure "procedure" doesn't have an argument "argument".
Explanation: procedure procedure does not have an argument named argument.
Corrective action: provide an argument from the procedure argument list.
::Simple::Proc::NO-TYPE-CHOICEMessage: argument "argument" from procedure "procedure" is not of type "choice" nor "choice-list".
Explanation: the extended procedure procedure argument argument type is not "choice" nor "choice-list".
::Simple::Proc::CANT-BE-CALLED-FROM-TOPLEVELMessage: "procedure" can't be called from the top level.
Explanation: it makes no sense to call procedure procedure from the top level.
Corrective action: call the procedure from a level other than the top one.
::Simple::Script::DUPLICATED-TAGMessage: duplicated header or trailer with tag "tag" in script "script".
Explanation: script script already contains a header or trailer with tag tag.
Corrective action: use ::Simple::Script::Header::delete or ::Simple::Script::Trailer::delete to delete the header with that tag or use another tag.
::Simple::Proc::VALUE-REQUIREDMessage: a value is required for optional or flag argument "optional or flag argument name".
Explanation: optional or flag argument optional or flag argument name requires a value, but no value was supplied.
Corrective action: supply a value for the optional or flag argument.
::Simple::Proc::ARRAY-NOT-ALLOWEDMessage: derived array type "type" not allowed for argument or option "argument or option name".
Explanation: a derived array type type has been used for argument or option argument or option name but that is not allowed.
Corrective action: for arguments, a derived array type can be emulated using upvar.
::Simple::Proc::OPTIONAL-FLAGMessage: cannot have an explicit optional flag "flag".
Explanation: flag flag was explicitly stated as optional while all flags are implicitly optional.
Corrective action: remove the question marks around the flag name.
For the sake of performance, this package does not implement some of the more esoteric features of the opt package such as argument names abbreviation, type guessing, completion of incomplete arguments or out of order flags (this last feature might be added in a future revision of the package).
For procedures with flags and a small number of arguments SimpleProc is about 20 times faster than the opt package, or 4 times if run-time type checking is enabled (notice that opt always checks the type of its arguments).
Also, several tricks are applied to improve performance (see the details section of the ::Simple::Proc::create procedure) which result in typical procedures (those which do not require argument run-time type checking and have no flags in the argument list) behaving identically to regular Tcl procedures (no run-time parsing is required).
For a ten non-flag arguments procedure, opt 0.4.4.1 requires 2810 microseconds per call (Tcl 8.4.9, 1.0 GHz Pentium III Mobile, Linux Red Hat 7.3) while SimpleProc uses a mere 3 or 740 microseconds when run-time type checking is disabled or enabled, respectively; that means performance improvement factors of 936 or 3.8, respectively. For a ten flag arguments procedure the figures are 2924 and 188 microseconds, a factor of 16.6. For a procedure with no arguments the figures are 90 and 2, a factor of 45. Even for procedures with flags, their parsing can be delegated to the user so, again, no overhead is introduced if desired.
The argument list internal representation of each extended procedure is stored in an element of the %ProcData% array in the procedure namespace whose index is %ArgInternal%,<unqualified procedure name>. This array element is a list with the following elements:
| 0 | whether the argument is a flag | 
| 1 | whether the argument has a default value | 
| 2 | argument name | 
| 3 | argument default value | 
| 4 | argument type | 
| 5 | argument choices (empty if type is not "choice" nor derived from it) | 
| 6 | argument description | 
The argument names list of each extended procedure argument list is stored in an element of the %ProcData% array in the procedure namespace whose index is %ArgNames%,unqualified procedure name.
The indices of the first and last flags in the argument list of each extended procedure argument is stored in an element of the %ProcData% array in the procedure namespace whose index is %FlagsIndices%,unqualified procedure name.
Whether the flag parsing is enabled or has been delegated to the user for each extended procedure is stored in an element of the %ProcData% array in the procedure namespace whose index is %ParseFlags%,unqualified procedure name.
The procedure access mode is stored in an element of the %ProcData% array in the procedure namespace whose index is %Access%,unqualified procedure name.
The procedure alias is stored in an element of the %ProcData% array in the procedure namespace whose index is %Alias%,unqualified procedure name.
The procedure metadata is stored in an element of the %ProcData% array in the procedure namespace whose index is %Metadata%,unqualified procedure name.
This package is optimized for speed and not for maintenability. In particular the run-time parsing of the argument list is done by one of two different private procedures (::Simple::Proc::Priv::parse-arguments and ::Simple::Proc::Priv::parse-arguments-checktype) depending on whether run-time type checking is enabled or not, even though they share most of the code.
Support out of order flags.
Allow derived arrary types as extended arguments.
It might be useful to have a way to enable and disable -checktype for existing procedures.
Provide a package option or flag to proc-ext to complain on bad flags throwing a ::Simple::BAD-FLAG error. Currently a bad flag is assumed to be a non-flag parameter.
Implement a mechanism to pass arguments by reference. This could sit on top of a new procedure named ::Simple::Argument::upvar which performs the upvar. It should have an -array flag which specifies whether the entity being linked via upvar is an array or a regular variable. It should also have an -exists (or -force) flag which, if given, asserts the array/value does exists. Independently on whether -exists is given or not, if the linked entity does exists we should assert that it is an array or a regular variable, as directed by -array being given or not.
::Simple::Argument::check-type argsSynopsis: perform runtime type checking on named arguments.
Access mode: public.
Keywords: argument and type.
Performs runtime type checking of specific arguments for the calling procedure when runtime type checking is turned off. If runtime type checking is turned on for the calling procedure, this procedure does nothing.
This procedure is useful to force run-time type checking for a subset of arguments even when run-time type checking is explicitly turned off.
# Create a procedure with runtime type checking turned off
# but that explicitly checks the type of ''arg2''
proc-ext -checktype false name {
   { arg1             integer        {First argument}}
   { arg2             choice {A B}   {Second argument}}
} {
  ::Simple::Argument::check-type arg2
}
# Invoke the command with non-conforming arguments. Notice that the
# error refers to ''arg2'' because ''arg1'' is not being type checked.
# This throws following error:
#   |invalid value "C" for argument "arg2" of type "choice": must be A or B
name foo C
Arguments:
| Argument | Type | Default value/ choices | Description | 
| args | list | (n/a) | List of argument names | 
Returns: whether runtime type checking was performed.
This procedure returns 1 even if there are no arguments to be checked.
::Simple::Argument::information choices procedure argumentSynopsis: returns an extended procedure argument choices list.
Access mode: public.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| procedure | commandname | (n/a) | Procedure name | 
| argument | unqualifiedname | (n/a) | Argument name | 
Returns: the extended procedure argument choices list.
::Simple::Argument::information default procedure argumentSynopsis: returns a procedure argument default value.
Access mode: public.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| procedure | commandname | (n/a) | Procedure name | 
| argument | unqualifiedname | (n/a) | Argument name | 
Returns: whether the procedure argument has a default value.
::Simple::Argument::information defaultgiven procedure argumentSynopsis: returns whether a procedure argument has a default value.
Access mode: public.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| procedure | commandname | (n/a) | Procedure name | 
| argument | unqualifiedname | (n/a) | Argument name | 
Returns: whether the procedure argument has a default value.
::Simple::Argument::information description procedure argumentSynopsis: returns an extended procedure argument description.
Access mode: public.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| procedure | commandname | (n/a) | Procedure name | 
| argument | unqualifiedname | (n/a) | Argument name | 
Returns: the extended procedure argument desription.
::Simple::Argument::information flaggiven flagSynopsis: returns whether a flag was given in an extended procedure call.
Access mode: public.
Keywords: procedure, argument and flag.
# A procedure with a single flag argument which echoes its value
# informing on whether that value is the default or was given in the
# argument list
proc-ext name {
   {-flag             string theflag {A flag (requires parameter)}}
} {
   puts -nonewline "flag      = <$flag> "
   if {[::Simple::Argument::information flaggiven -flag]} {
      puts "(flag given)"
   } else {
      puts "(default value)"
   }
}
Arguments:
| Argument | Type | Default value/ choices | Description | 
| flag | flag | (n/a) | Flag name | 
Returns: whether the flag was given in the actual argument list.
Limitations:
This procedure must be called from another procedure.
The ::Simple::Argument::information givenflags procedure.
The ::Simple::Priv::flag-given procedure.
The ::Simple::Option::information usage procedure.
::Simple::Argument::information givenflagsSynopsis: returns the flags and their parameters in an extended procedure call.
Access mode: public.
Keywords: procedure, argument and flag.
This procedure returns the list of flags and their parameters given in an extended procedure call. The format of the returned list is suitable to be given as argument to the array get command: the array indices would be the flags and the array values their parameters.
Notice that for boolean flags (type "boolflag") the value is always 1.
Arguments: none.
Returns: the list of flags and their parameters given in the actual argument list.
Limitations:
This procedure must be called from another procedure.
The ::Simple::Argument::information flaggiven procedure.
The ::Simple::Priv::flag-given procedure.
The ::Simple::Option::information usage procedure.
::Simple::Argument::information isdefault argumentSynopsis: returns whether an argument value is the default one.
Access mode: public.
Keywords: procedure, argument and default value.
For flags or optional arguments, this procedure returns whether its actual value matches its corresponding default value. For other arguments the procedure returns always false.
# A procedure with an optional argument whose default value
# is rather estrange, value which is used to check whether
# the argument was given in the actual argument list
proc-ext name {
   {?argument?   string %DEFAULT%      {Optional argument}}
} {
   if {[::Simple::Argument::information isdefault argument]} {
      puts {argument not given}
   } else {
      puts "argument given = $argument"
   }
}
Arguments:
| Argument | Type | Default value/ choices | Description | 
| argument | unqualifiedname | (n/a) | Argument name | 
Returns: whether the argument has a default value and it matches its actual value.
Limitations:
This procedure must be called from another procedure.
The ::Simple::Option::information isdefault procedure.
::Simple::Argument::information type procedure argumentSynopsis: returns an extended procedure argument type.
Access mode: public.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| procedure | commandname | (n/a) | Procedure name | 
| argument | unqualifiedname | (n/a) | Argument name | 
Returns: the extended procedure argument type.
::Simple::Proc::cget ?-checktype? ?-afterflags?Synopsis: gets the package options.
Access mode: public.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| -checktype | boolflag | (n/a) | Gets whether to perform run-time type checking of the procedures arguments | 
| -afterflags | boolflag | (n/a) | Gets the minimum number of arguments after the last flag for a procedure in order for those to be handled with an auxiliary "after flags" procedure | 
Returns: the requested option value or the whole list of options if none specified.
::Simple::Proc::configure ?-checktype extbool? ?-afterflags integer?Synopsis: configures the package options.
Access mode: public.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| ?-checktype? | extbool | false | Whether to perform run-time type checking of the procedures arguments | 
| ?-afterflags? | integer | 5 | Minimum number of arguments after the last flag for a procedure in order for those to be handled with an auxiliary "after flags" procedure | 
Returns: the empty string.
proc-ext ?-parseflags extbool? ?-checktype extbool? procedure arguments body(Alias for ::Simple::Proc::create).
Synopsis: creates a procedure with extended argument syntax.
Access mode: public.
Keywords: procedure, argument, type and flag.
This procedure acts as an interface to the proc command to create other procedures allowing a richer syntax for their arguments. Upon creation of a new procedure, its extended format argument list is parsed and converted into a canonical argument list (in which each argument has the format {name ?defaultValue?}) which is used to actually create the procedure via the proc command. If the argument list contains one or more flags, or if run-time type checking is requested, the procedure body is instrumented to add run-time handling of the argument list.
If the procedure name is two words, a subcommand procedure similar to that created via the SimpleSubcommand package proc-sub procedure is created, but with extended argument syntax. It is thus not required to use proc-sub when using this package.
Extended syntax arguments are of the form {name type ?value? description}
Arguments whose name starts by a hyphen are flags. The presence of flags in the procedure call actual argument list is optional but.
Flags whose type is boolflag are boolean flags and do not require a parameter. For each boolean flag in the argument list, a variable is created in the procedure body with the same name as the flag (excluding the hyphen) and whose value is true or false (1 or 0) depending on whether the flag is given or not in the procedure call actual argument list.
Flags whose type is not boolflag are regular flags and require a parameter; the flag type is the expected parameter type. For each regular flag in the argument list, a variable is created in the procedure body with the same name as the flag (excluding the hyphen) and whose value is the parameter supplied after the flag, or its default value if the flag was not given in the procedure call actual argument list. The presence or absence of a regular flag in the procedure call actual argument list can be checked via the ::Simple::Argument::information flaggiven procedure.
The list of all flags in the procedure call actual argument list together with their parameters can be obtained via the ::Simple::Argument::information givenflags.
Arguments whose name is enclosed between question marks are optional. They differ from the flags in that they behave exactly as optional arguments to the proc command, that is, they must appear at the end of the argument list.
As with the proc command, the args special argument collects all remaining arguments in the actual argument list and combines them into a list which is available to the procedure body in the variable name args. If given, the args special argument must be the last one.
The argument type must be a type known by The Simple Development Library, that is, any Simple Development Library type or declared via the ::Simple::Type::declare procedure.
An actual argument whose type is choice can only hold one of the values specified in the argument declaration default value field.
See also the boolflag type in the argument name section above.
An argument declaration can specify this field if and only if its type is choice, an optional argument, or a flag whose type is not boolflag. For arguments of type choice, this field specifies the list of allowed choices; otherwise, it corresponds to the parameter default value. For optional arguments of type choice, the default value is the first choice.
This is simply a description of the argument.
The -checktype flag allows to override the package option of the same name for the procedure being created. This option controls whether a run-time type check is performed to assess whether the arguments contents match their type. This has a performance penalty which should be considered. The overhead comes from two fronts. First, the contents of each argument must be checked. Second, it is not possible to apply the improving performance tricks described in the details section below.
The -parseflags flag allows to disable the flag parsing which is delegated to the user. This results in better performance (the procedure call is equivalent to a regular Tcl proc procedure) at the cost of some hassle and restrictions:
The arguments from the first flag are replaced by the args special argument. It is the user responsibility to handle the args special argument to attain the desired behaviour. See the puts clone in the examples section below.
No run-time type checking of the procedure arguments is performed. As a result, it is not allowed to supply both the -parseflags and -checktype flags. If the -checktype package option is set to true, it is not honored.
# A regular procedure
proc-ext name {
   {-boolflag         boolflag       {A boolean flag}}
   { arg1             string         {First argument}}
   { arg2             integer        {Second argument}}
   { arg3             choice {foo bar}
                                     {Choice between foo and bar}}
   {-flag             string theflag {A flag (requires parameter)}}
   {?arg4?            string default {Optional argument}}
   { args             list           {Remaining arguments}}
} {
   puts "-boolflag = <$boolflag>"
   puts "arg1      = <$arg1>"
   puts "arg2      = <$arg2>"
   puts "arg3      = <$arg3>"
   puts -nonewline "flag      = <$flag> "
   if {[::Simple::Argument::information flaggiven -flag]} {
      puts "(flag given)"
   } else {
      puts "(default value)"
   }
   puts "arg4      = <$arg4>"
   puts "args      = <$args>"
}
# A subcommand procedure for which the contents of
# their arguments is run-time type checked
proc-ext -checktype true {command subcommand} {
   {-boolflag         boolflag       {A boolean flag}}
   { arg1             string         {First argument}}
   { arg2             integer        {Second argument}}
} {
   puts "-boolflag = <$boolflag>"
   puts "arg1      = <$arg1>"
   puts "arg2      = <$arg2>"
}
# A clone of puts (except in that it requires the channel)
# with flag parsing delegated to the user
proc-ext -parseflags false puts-clone {
   {-nonewline        boolflag       {Do not append a newline}}
   { channelId        channel        {Output channel}}
   { string           string         {String to write}}
} {
   foreach {arg1 arg2 arg3} $args break
   if {![string compare $arg1 -nonewline]} {
      puts -nonewline  $arg2 $arg3
   } else {
      puts             $arg1 $arg2
   }
}
Arguments:
| Argument | Type | Default value/ choices | Description | 
| ?-parseflags? | extbool | true | Whether to enable flag parsing or delegate it to the user | 
| ?-checktype? | extbool | false | Whether to enable argument run-time type checking | 
| procedure | commandname | (n/a) | Procedure name | 
| arguments | extendedarg-list | (n/a) | Extended argument list | 
| body | script | (n/a) | Procedure body | 
Returns: the empty string.
Effects:
Creates a command named procedure.
May create an "after flags" command named name-%AFTER-FLAGS% where name is the qualified name of the procedure or method being created.
If -parseflags false is given, the actual procedure which is created has the first flag and following arguments replaced by the args special argument. The procedure body is not instrumented.
If run-time type checking is enabled, the actual procedure which is created has no arguments. A call to the ::Simple::Proc::Priv::parse-arguments-checktype procedure is added at the very beginning of the procedure body to perform the required run-time parsing and checking.
If run-time type checking is disabled, the arguments to the procedure are divided into three sets: arguments before the first flag, arguments from the first to the last flag and arguments after the last flag. The actual procedure which is created contains the first set of arguments; the second and third sets are handled by a call to the ::Simple::Proc::Priv::parse-arguments procedure which is added at the very beginning of the procedure body to perform the required run-time parsing. If the number of arguments in the third set exceeds the -afterflags package option value, those are handled via an auxiliary "after flags" procedure instead.
If the procedure namespace does not exists it is not created. This mimics the behaviour of the proc command.
The "after flags" procedure is named name-%AFTER-FLAGS% where name is the qualified name of the procedure or method being created.
The list of flags given in the actual argument list is stored in a variable named %GIVEN-FLAGS% in the scope of the procedure being created.
The header added to the script body when argument run-time type checking is enabled is tagged as %PRIV%-parse-arguments or %PRIV%-parse-arguments-checktype with priority 0.
The order of the -parseflags and -checktype flags is irrelevant, but both of them must appear before the procedure name.
::Simple::Proc::delete procedureSynopsis: deletes a procedure.
Access mode: public.
This command is similar to the rename command when its second argument is the empty string, but works for extended procedures as well as for regular procedures.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| procedure | commandname | (n/a) | Procedure name | 
Returns: the empty string.
Effects:
Deletes the procedure named procedure.
No aliases for the procedure are deleted.
::Simple::Proc::information access procedureSynopsis: returns a declared procedure access mode.
Access mode: public.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| procedure | commandname | (n/a) | Procedure name | 
Returns: the declared procedure access mode.
::Simple::Proc::information alias procedureSynopsis: returns a declared procedure alias.
Access mode: public.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| procedure | commandname | (n/a) | Procedure name | 
Returns: the declared procedure alias.
::Simple::Proc::information args procedureSynopsis: returns a procedure argument names list.
Access mode: public.
This command is similar to the info args command, but works for extended procedures as well as for regular procedures.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| procedure | commandname | (n/a) | Procedure name | 
Returns: the procedure argument names list.
::Simple::Proc::information arguments procedureSynopsis: returns a procedure argument list.
Access mode: public.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| procedure | commandname | (n/a) | Procedure name | 
Returns: the procedure argument list.
::Simple::Proc::information body procedureSynopsis: returns a procedure body.
Access mode: public.
This command is similar to the info body, but works for extended procedures as well as for regular procedures.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| procedure | commandname | (n/a) | Procedure name | 
Returns: the procedure body.
::Simple::Proc::information caller ?levels?Synopsis: returns the caller procedure name.
Access mode: public.
This procedure returns the name of a procedure up the calling stack. By default, one level up the stack is used.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| ?levels? | integer | 1 | Levels up the stack in which to operate | 
Returns: the caller procedure name or the empty string if not found.
::Simple::Proc::information checktype procedureSynopsis: returns whether a procedure performs argument type checking.
Access mode: public.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| procedure | commandname | (n/a) | Procedure name | 
Returns: whether the procedure performs argument type checking.
This procedure returns false for non-existing or non-extended procedures.
This procedure returns true for extended procedures with no arguments.
::Simple::Proc::information exists procedureSynopsis: returns whether a procedure exists.
Access mode: public.
This command returns whether a procedure exists, being it extended or not.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| procedure | commandname | (n/a) | Procedure name | 
Returns: whether the procedure exists.
::Simple::Proc::information isextended procedureSynopsis: returns whether a procedure is an extended procedure.
Access mode: public.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| procedure | commandname | (n/a) | Procedure name | 
Returns: whether the extended procedure exists.
::Simple::Proc::information issubcommand procedureSynopsis: returns whether a procedure is a base command procedure.
Access mode: public.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| procedure | commandname | (n/a) | Procedure name | 
Returns: whether the procedure is a base command procedure.
The ::Simple::Subcommand::information exists procedure.
::Simple::Proc::information metadata procedureSynopsis: returns a declared procedure metadata.
Access mode: public.
This procedure returns a list of pairs suitable to be given as argument to the array set command. Each element is one of the flags given to declare-proc upon procedure declaration (with no hypen), but for -arguments, -access, -alias and -body (these are obtained using specific ::Simple::Proc::information subcommands), and the items stored by proc-ext (parseflags and checktype; these are also obtained using specific ::Simple::Proc::information subcommands).
Thus, the actual list of flags is: -version, -project, -synopsis, -overview, -returns, -keywords, -examples, -assumptions, -resources, -limitations, -effects, -details, -references, -remarks, -todo, -history and -copyright.
Notice that no data is returned unless The Simple Development Library -storemetadata option is set when the procedure was declared.
If a particular flag was not given in the procedure declaration, the empty string is returned as that flag contents.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| procedure | commandname | (n/a) | Procedure name | 
Returns: the declared procedure metadata as an item/contents pairs list.
::Simple::Proc::information parseflags procedureSynopsis: returns whether a procedure has flag parsing enabled.
Access mode: public.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| procedure | commandname | (n/a) | Procedure name | 
Returns: whether the procedure has flag parsing enabled.
This procedure returns false for non-existing or non-extended procedures.
::Simple::Proc::information runtimeparsing procedureSynopsis: returns whether a procedure run-time parses its arguments.
Access mode: public.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| procedure | commandname | (n/a) | Procedure name | 
Returns: whether the procedure run-time parses its arguments.
This procedure returns false for non-existing or non-extended procedures.
::Simple::Proc::information subcommands commandSynopsis: returns a base command procedure subcommand list.
Access mode: public.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| command | name | (n/a) | Base command name | 
Returns: the base command procedure subcommand list.
The ::Simple::Subcommand::information subcommands procedure.
Procedures containing a percent sign in its name are assumed to be internal to The Simple Development Library and are excluded from the output.
::Simple::Proc::information usage procedureSynopsis: returns a procedure argument usage string.
Access mode: public.
# A procedure with several arguments, including flags
proc-ext name {
   { arg1             integer        {First regular argument}}
   {-boolflag         boolflag       {Boolean flag}}
   {-flag1            string  FLAG1  {First flag}}
   {-flag2            string  FLAG2  {Second flag}}
   { arg2             integer        {Second regular argument}}
} {
}
# This displays the following:
#   |arg1 ?-boolflag? ?-flag1 string? ?-flag2 string? arg2
puts [::Simple::Proc::information usage name]
Arguments:
| Argument | Type | Default value/ choices | Description | 
| procedure | commandname | (n/a) | Procedure name | 
Returns: the procedure argument usage string.
The ::Simple::Option::information usage procedure.
This command works for extended procedures as well as for regular procedures.
::Simple::Proc::move sourceProcedure targetProcedureSynopsis: renames a procedure.
Access mode: public.
This command is similar to the rename command when its second argument is non-empty, but works for extended procedures as well as for regular procedures.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| sourceProcedure | name | (n/a) | Source procedure name | 
| targetProcedure | name | (n/a) | Target procedure name | 
Returns: the empty string.
Effects:
Renames the procedure named sourceProcedure to targetProcedure.
If the target procedure namespace does not exists, it is created. This mimics the behaviour of the rename command.
Allow to rename from subcommand to regular procedures and viceversa.
::Simple::Proc::resolve-alias procedureSynopsis: resolves command aliases.
Access mode: public.
This procedure resolves one aliasing level for a command, if existing.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| procedure | name | (n/a) | Procedure name | 
Returns: the alias resolved command name.
Limitations:
Just one aliasing level is resolved.
::Simple::Script::Header::add scriptName tag priority headerSynopsis: prepends a header to a script.
Access mode: public.
This command prepends a header to a script.
The header is enclosed between a begin and an end of header markers formatted through the MarkerFormat package variable. Both markers contain the header tag and priority. Successive headers within a script are ordered by increasing priority which goes from 0 to 9999. If a header with the same priority as the one being prepended already exists, the original has precedence, that is, the later gets added after the former.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| scriptName | name | (n/a) | Script name | 
| tag | string | (n/a) | Header tag | 
| priority | integer | (n/a) | Header priority | 
| header | script | (n/a) | Header | 
Returns: the empty string.
Effects:
Prepends the header to the script called scriptName in the calling scope.
::Simple::Script::Header::delete scriptName ?pattern?Synopsis: deletes headers from a script.
Access mode: public.
This procedure deletes script headers added by ::Simple::Script::Header::add matching the given pattern.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| scriptName | name | (n/a) | Script name | 
| ?pattern? | pattern | (empty string) | Pattern | 
Returns: the number of deleted headers.
Effects:
Deletes the headers from the script called scriptName in the calling scope.
Use no pattern to delete all headers.
::Simple::Script::Header::get script ?pattern?Synopsis: gets headers from a script.
Access mode: public.
This procedure returns the list of headers from a script added by ::Simple::Script::Header::add matching the given pattern.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| script | script | (n/a) | Script | 
| ?pattern? | pattern | (empty string) | Pattern | 
Returns: the list of script headers matching the given pattern in the format {tag priority header}.
Use no pattern to get all headers.
::Simple::Script::Trailer::add scriptName tag priority trailerSynopsis: appends a trailer to a script.
Access mode: public.
This command appends a trailer to a script.
The trailer is enclosed between a begin and an end of trailer markers formatted through the MarkerFormat package variable. Both markers contain the trailer tag and priority. Successive trailers within a script are ordered by increasing priority which goes from 0 to 9999. If a trailer with the same priority as the one being appended already exists, the original has precedence, that is, the later gets added after the former.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| scriptName | name | (n/a) | Script name | 
| tag | string | (n/a) | Trailer tag | 
| priority | integer | (n/a) | Trailer priority | 
| trailer | script | (n/a) | Trailer | 
Returns: the empty string.
Effects:
Appends the trailer to the script called scriptName in the calling scope.
::Simple::Script::Trailer::delete scriptName ?pattern?Synopsis: deletes trailers from a script.
Access mode: public.
This procedure deletes script trailers added by ::Simple::Script::Trailer::add matching the given pattern.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| scriptName | name | (n/a) | Script name | 
| ?pattern? | pattern | (empty string) | Pattern | 
Returns: the number of deleted trailers.
Effects:
Deletes the trailers from the script called scriptName in the calling scope.
Use no pattern to delete all trailers.
::Simple::Script::Trailer::get script ?pattern?Synopsis: gets trailers from a script.
Access mode: public.
This procedure returns the list of trailers from a script added by ::Simple::Script::Trailer::add matching the given pattern.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| script | script | (n/a) | Script | 
| ?pattern? | pattern | (empty string) | Pattern | 
Returns: the list of script trailers matching the given pattern in the format {tag priority header}.
Use no pattern to get all trailers.
::Simple::Script::append scriptName scriptToAppendSynopsis: appends a non-empty script to another one.
Access mode: public.
Arguments:
| Argument | Type | Default value/ choices | Description | 
| scriptName | name | (n/a) | Script name | 
| scriptToAppend | script | (n/a) | Script to append | 
Returns: the empty string.
Effects:
Appends the scriptToAppend to the script called scriptName in the calling scope.