cmdr
Check-in [6b1f531bbb]
Not logged in
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2018 Conference, Houston/TX, US, Oct 15-19
or submit via the online form by Aug 20.

Overview
Comment: Added docs for the flow at runtime. Documented some of the reserved common blocks. family | ancestors | descendants | both | trunk files | file ages | folders 6b1f531bbbf5590c2f792c7bf3e80fc08b39dadf andreask 2013-11-28 19:21:42
Context
 2013-11-28 22:35 Moved old docs into an attic. Completed the todos, except very minor parts. Includes backend example, reserved blocks. Added, completed DSL informaton, mainly where to find them, and how DSL commands map to methods. check-in: eed0701b51 user: andreask tags: trunk 19:21 Added docs for the flow at runtime. Documented some of the reserved common blocks. check-in: 6b1f531bbb user: andreask tags: trunk 05:39 Another round of tweaking labels for nicer sorting. check-in: df97aa496f user: aku tags: trunk
Changes

Changes to doc/cmdr_dsl.man.

 6 7 8 9 10 11 12 13 14 15 16 17 18 19  [include parts/welcome.inc] This document is for users of the cmdr framework. It introduces the domain-specific language for the specification of command hierarchies with commands and their parameters by way of examples and then provides links to the detailed reference documents. [include parts/related_dsl.inc] [comment @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@] [section {Introductory examples}] Instead of immediately diving into the full syntax of the specification language first a few examples to demonstrate the general   >  6 7 8 9 10 11 12 13 14 15 16 17 18 19 20  [include parts/welcome.inc] This document is for users of the cmdr framework. It introduces the domain-specific language for the specification of command hierarchies with commands and their parameters by way of examples and then provides links to the detailed reference documents. [comment @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@] [include parts/related_dsl.inc] [comment @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@] [section {Introductory examples}] Instead of immediately diving into the full syntax of the specification language first a few examples to demonstrate the general 

Changes to doc/cmdr_dsl_parameter.man.

 9 10 11 12 13 14 15 16 17 18 19 20  domain-specific language for the specification of parameters in detail. [include parts/related_dsl.inc] [section {Language Reference}] [include parts/dsl_parameter.inc] [include parts/related.inc] [include parts/feedback.inc] [manpage_end]   > >  9 10 11 12 13 14 15 16 17 18 19 20 21 22  domain-specific language for the specification of parameters in detail. [include parts/related_dsl.inc] [section {Language Reference}] [include parts/dsl_parameter.inc] [para] Please continue reading with [term [vset TITLE_FLOW]]. [include parts/related.inc] [include parts/feedback.inc] [manpage_end] 

     > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44  [include parts/definitions.inc] [manpage_begin [vset LABEL_FLOW] [vset MAN_SECTION] [vset VERSION]] [include parts/module.inc] [titledesc [vset TITLE_FLOW]] [description] [include parts/welcome.inc] This document is for users of the cmdr framework. If you have not read [term [vset TITLE_DSL]] and the related documents yet, please do so. The explanations how the framework processes a command line at runtime guided by a specified command hierarchy presuppose knowledge of command-hierarchy specifications. [para] A command line is processed in four distinct phases, namely [sectref Dispatch], [sectref Parsing], [sectref Completion], and [sectref Execution]. Each is explained in more detail in the referenced sections. [comment @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@] [include parts/related_dsl.inc] [comment @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@] [section Dispatch] [include parts/flow_dispatch.inc] [comment @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@] [section Parsing] [include parts/flow_parsing.inc] [comment @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@] [section Completion] [include parts/flow_completion.inc] [comment @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@] [section Execution] [include parts/flow_execution.inc] [include parts/related.inc] [include parts/feedback.inc] [manpage_end] 

Changes to doc/cmdr_help.man.

 47 48 49 50 51 52 53 54 55 56  [section {Format Notes}] The format [const by-category] looks for and uses the block [const *category-order*] for when the user wishes to override the natural (alphabetical) order of display for the toplevel sections. [para] This block has to be defined in the root of the command hierarchy. [include parts/feedback.inc] [manpage_end]   > >  47 48 49 50 51 52 53 54 55 56 57 58  [section {Format Notes}] The format [const by-category] looks for and uses the block [const *category-order*] for when the user wishes to override the natural (alphabetical) order of display for the toplevel sections. [para] This block has to be defined in the root of the command hierarchy. @EDIT --TODO-- details of the *category-order* definition. [include parts/feedback.inc] [manpage_end] 

Changes to doc/cmdr_howto_development.man.

 102 103 104 105 106 107 108 109 110 111 112 113  [term [vset TITLE_HELP]]) as well. [comment @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@] [section {Command Line Completion}] The document [term [vset TITLE_DEV_COMPLETE]] describes the inner workings of the command line completion provided by the framework. [comment @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@] [include parts/related.inc] [include parts/feedback.inc] [manpage_end]   > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >  102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145  [term [vset TITLE_HELP]]) as well. [comment @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@] [section {Command Line Completion}] The document [term [vset TITLE_DEV_COMPLETE]] describes the inner workings of the command line completion provided by the framework. [comment @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@] [section {Common Blocks}] The framework reserves all blocks whose name begins with a star, i.e [const *], for its own use. Currently the following names are in use: [list_begin definitions] [def [const *all*]] Publicly documented for users, this block is expected to contain parameter specification commands. These commands are automatically added to all privates found in the command hierarchy containing the block. [para] The details are explained by the description of command [cmd common] in [term [vset TITLE_DSL_OFFICER]]. [def [const *category-order*]] Publicly documented for users, this block is expected to contain a dictionary mapping from toplevel section/category names to an integer number to override the natural order of displaying these sections in the help. [para] The details are explained in section [term {Format Notes}] of [term [vset TITLE_HELP]]. [def [const *prefix*]] --@EDIT todo-document--internal [def [const *in-shell*]] --@EDIT todo-document--public-where? [list_end] [comment @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@] [include parts/related.inc] [include parts/feedback.inc] [manpage_end] 

Changes to doc/parts/definitions.inc.

 22 23 24 25 26 27 28 29 30 31 32 33 34 35 .. 50 51 52 53 54 55 56  [vset TITLE_HELP_SQL "[vset PTITLE] - Formatting help as series of SQL commands"] [vset TITLE_OFFICER "[vset PTITLE] - (Internal) Aggregation of multiple commands for dispatch."] [vset TITLE_PARAMETER "[vset PTITLE] - (Partially internal) Command parameters"] [vset TITLE_PRIVATE "[vset PTITLE] - (Internal) Single command handling, options, and arguments"] [vset TITLE_UTIL "[vset PTITLE] - (Internal) General Utilities"] [vset TITLE_VALIDATE "[vset PTITLE] - Standard validation types for parameters"] [vset TITLE_VCOMMON "[vset PTITLE] - Utilities for Validation Types"] [comment {- Miscellanea ............. - - -- --- ----- --------}] [vset LABEL_INTRO [vset PROJECT]-introduction] [vset LABEL_LICENSE [vset PROJECT]-license] [vset LABEL_CHANGES [vset PROJECT]-changes] [vset LABEL_SOURCES [vset PROJECT]-howto-get-sources] [vset LABEL_INSTALL [vset PROJECT]-installation] ................................................................................ [vset LABEL_HELP_SQL [vset PROJECT]::help::sql] [vset LABEL_OFFICER [vset PROJECT]::officer] [vset LABEL_PARAMETER [vset PROJECT]::parameter] [vset LABEL_PRIVATE [vset PROJECT]::private] [vset LABEL_UTIL [vset PROJECT]::util] [vset LABEL_VALIDATE [vset PROJECT]::validate] [vset LABEL_VCOMMON [vset PROJECT]::validate::common]   > >  22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 .. 51 52 53 54 55 56 57 58  [vset TITLE_HELP_SQL "[vset PTITLE] - Formatting help as series of SQL commands"] [vset TITLE_OFFICER "[vset PTITLE] - (Internal) Aggregation of multiple commands for dispatch."] [vset TITLE_PARAMETER "[vset PTITLE] - (Partially internal) Command parameters"] [vset TITLE_PRIVATE "[vset PTITLE] - (Internal) Single command handling, options, and arguments"] [vset TITLE_UTIL "[vset PTITLE] - (Internal) General Utilities"] [vset TITLE_VALIDATE "[vset PTITLE] - Standard validation types for parameters"] [vset TITLE_VCOMMON "[vset PTITLE] - Utilities for Validation Types"] [vset TITLE_FLOW "[vset PTITLE] - Runtime Processing Flow"] [comment {- Miscellanea ............. - - -- --- ----- --------}] [vset LABEL_INTRO [vset PROJECT]-introduction] [vset LABEL_LICENSE [vset PROJECT]-license] [vset LABEL_CHANGES [vset PROJECT]-changes] [vset LABEL_SOURCES [vset PROJECT]-howto-get-sources] [vset LABEL_INSTALL [vset PROJECT]-installation] ................................................................................ [vset LABEL_HELP_SQL [vset PROJECT]::help::sql] [vset LABEL_OFFICER [vset PROJECT]::officer] [vset LABEL_PARAMETER [vset PROJECT]::parameter] [vset LABEL_PRIVATE [vset PROJECT]::private] [vset LABEL_UTIL [vset PROJECT]::util] [vset LABEL_VALIDATE [vset PROJECT]::validate] [vset LABEL_VCOMMON [vset PROJECT]::validate::common] [vset LABEL_FLOW [vset PROJECT]-spec-flow] 

Changes to doc/parts/dsl_officer.inc.

 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121   This is an advanced command which should normally only be specified at the top of the whole hierarchy (from which its value will automatically propagate to all subordinates). [para] At runtime the framework will call the specified command prefix with a single argument, a script whose execution is equivalent to the phases "Parsing", "Completion", and "Execution" of the framework, as described in --TODO--(sectref:flow/phases)--. The handler [emph must] call this script, and can perform any application-specific actions before and after. [para] This handler's main uses are two-fold: [list_begin enumerated] [enum] Capture and hande application-specific errors which should not abort the application, nor shown as Tcl stacktrace.   | | > | |  104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122   This is an advanced command which should normally only be specified at the top of the whole hierarchy (from which its value will automatically propagate to all subordinates). [para] At runtime the framework will call the specified command prefix with a single argument, a script whose execution is equivalent to the phases [term Parsing], [term Completion], and [term Execution] of the framework, as described in [term [vset TITLE_FLOW]]. The handler [emph must] call this script, and can perform any application-specific actions before and after. [para] This handler's main uses are two-fold: [list_begin enumerated] [enum] Capture and hande application-specific errors which should not abort the application, nor shown as Tcl stacktrace. 

Changes to doc/parts/dsl_para_general.inc.

 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50  [comment {- - -- --- ----- -------- -------------}] [call [cmd test]] This command is related to the above, switching the runtime from the standard regime for acceptance (based on counting and thresholds) to a different regime based on validation. The details are explained in --TODO--(sectref:flow/parsing,flow/optional)--. [comment {- - -- --- ----- -------- -------------}] [call [cmd undocumented]] This command excludes the [term parameter] from the generated help. [para] Its main use case is the hiding of [term option]s giving an   | >  36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51  [comment {- - -- --- ----- -------- -------------}] [call [cmd test]] This command is related to the above, switching the runtime from the standard regime for acceptance (based on counting and thresholds) to a different regime based on validation. [para] More details are explained in section [term Parsing] of [term [vset TITLE_FLOW]]. [comment {- - -- --- ----- -------- -------------}] [call [cmd undocumented]] This command excludes the [term parameter] from the generated help. [para] Its main use case is the hiding of [term option]s giving an 

     > > > > > > > > > > > > > > > > > > > > > > > > > >  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26   [para] This phase is reached when all words of the command line have been processed and no error was thrown by the preceding phases. At this point we know the [package cmdr::private] instance to use, and its parameters may have a string representation. [para] All [term immediate]-mode parameters are now given their internal representation. The parameters marked as [term defered] are ignored here and will get theirs on first access by the backend. [para] This completion of parameters is done in their order of declaration within the enclosing [term private] command. Note that when parameters have dependencies between them, i.e. the calculation of their internal representation requires the internal representation of another parameter, then this order may be violated as the requesting parameter triggers completion in the requested one on access. If this is behaviour not wanted then it is the responsibility of the user specifying the [term private] to place the parameters into an order where all parameters access only previously completed parameters during their own completion. 

     > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32   [para] The first phase determines the [package cmdr::private] instance to use. To this end it processes words from the command line and uses them to navigate the tree of [package cmdr::officer] instances until a [term private] is reached. [para] Each word of the command line is treated as the name of the [package cmdr::officer] instance to descend into. An error will be thrown when encountering a name for which there is no known actor (officer or private), and the current [term officer] has no [term default] declared for it. [para] On the converse, when reaching the end of the command line but not reaching a [term private] the framework will not throw an error. It will start an interactive command line shell instead. This [term {main shell}] provides access to exactly the commands of the [package cmdr::officer] instance which was reached, plus two pseudo-commands to either exit this shell or gain help. [para] Execution of the command tree specification, i.e. the generation of the in-memory command tree and the actor instances bound in it, is intertwined with this descent through the command tree. I.e. instead of processing the entire specification immediately in full it is lazily unfolded on demand, ignoring all parts which are not needed. Note that the generated data structures are not destroyed after [sectref Execution], but kept, avoiding the need to re-parse the parts of the specification already used at least once when an interactive command line shell is active. 

     > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89   [para] The last phase is also the most simple. [para] It only invokes the Tcl command prefix associated with the chosen [package cmdr::private] instance, providing it with the [package cmdr::config] instance holding the parameter information extracted from the command line as its single argument. [para] Listing --TODO--backend-example-\ref{ex/execution} is an example of very simple action implementations, matching to the example specifications provided in [term [vset TITLE_DSL]] [para] All parameters declared for a [term private] are made accessible through individual methods associated with each. As example, a parameter with system name [var P] is mapped to the method [method @P], with all instance methods provided by the [package cmdr::parameter] class accessible as sub-methods. This general access to all methods may be removed in the future, restricting actions and callbacks to a safe subset. [comment { @EDIT --todo-- figure out if we want this table (safe para methods) in the docs, and where A first approximation of such a set can be found in the table below. [example { cmdline & True if the parameter accessible on command line. \\ config \arg{...} & Access to the methods of the container the parameter belongs to, and thus all other parameters of the private. \\ default & Default value, if specified. See \cmd{hasdefault}. \\ defered & True if the internal representation is generated on demand. \\ description \arg{?detail?} & Help text. May be generated. \\ documented & True if the parameter is not hidden from help. \\ forget & Squash the internal representation. See also \cmd{reset}. \\ generator & Command prefix to generate a default value (internal representation). \\ hasdefault & True if a default value was specified. See \cmd{default}. \\ help & Help structure describing the parameter. \\ interactive & True if the parameter allows interactive entry of its value. \\ is \arg{type} & Check if the result of \cmd{type} matches the argument. \\ isbool & True if the parametr is a boolean option. \\ list & True if the parameter holds a list of values. \\ lock \arg{reason} & For use in \cmd{when-set} callbacks. Allows parameters to exclude each other's use. \\ locker & The \arg{reason} set by \cmd{lock}, if any. \\ name & The parameter's name. \\ options & List of option flags, if any. \\ ordered & True if the parameter is positional. \\ presence & True if the parameter is a boolean option not taking arguments. \\ primary \arg {option} & True if the provided flag name is the primary option to be recognized (instead of an alias, or complement). \\ prompt & Text used as prompt during interactive entry. \\ required & True if the option is mandatory (\const(input) only). \\ reset & Squash internal and string representations. See also \cmd{forget}. \\ self & The parameter's instance command \\ set \arg{value} & Programmatically set the string representation. \\ set? & True if the string representation was set. \\ string & Return the string representation, or error. \\ type & Parameter type. One of \const{input}, \const{option}, or \const{state}. \\ validator & Command prefix used to validate the string representation and transform it into the internal representation. \\ value & Return the internal representation. May calculate it now from the string representation. \\ when-complete & Command prefix invoked when the internal representation is set. \\ when-set & Command prefix invoked when the string representation is set. \\ }] }] [para] Calling [method @P] without arguments is a shorthand for calling @P value'', i.e. the retrieval of the parameter's internal representation. Which may calculate the value if the call is the first access and the parameter specified as [term defered]. 
     > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > >  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122   [vset EXAMPLE_T {Example for Handling optional Inputs by Threshold}] [para] This is the most complex phase internally, as it has to assign the left-over words to the parameters of the chosen [package cmdr::private] instance, taking into account the kind of parameters, their requiredness, listness, and other attributes. [para] Generally processing the words from left to right [term options] are detected in all positions, through their flags (primary, aliases, and all unique prefixes), followed by their (string) value to assign. [para] When a word cannot be the flag for an option the positional [term inputs] are considered, in order of their declarations. For a mandatory [term input] the word is simply assigned as its string value and processing continues with the next word, and the next [term input], if any. Operation becomes more complex when the [term input] under consideration is [term optional]. Now it is necessary to truly decide if the word should be assigned to this [term input] or the following. [para] The standard method for this decision is to count words and compare to the count of mandatory [term inputs] left. If there are more words available than required to satisfy all mandatory [term inputs], then we can and do assign the current word to the optional input. Otherwise the current [term input] is skipped and we consider the next. A set of condensed examples can be found in section [sectref [vset EXAMPLE_T]]. They demonstrate how a various numbers of argument words are assigned to a specific set of [term inputs], [term optional] and non. This is called the [term threshold] algorithm. [para] The non-triviality in the above description is in the phrase to [term {count words}]. We cannot simply count all words left on the command line. To get a proper count we have discard/ignore all words belonging to options. At this point the processor essentially works ahead, processing and removing all flags/options and their arguments from the command line before performing the comparison and making its decision. [para] The whole behaviour however can be changed via [cmd test] (See section [term {General control}] of [term [vset TITLE_DSL_PARAMETER]]). Instead of counting words the current word is run through the validation type of the current [term input]. On acceptance the value is assigned to it, otherwise that [term input] is skipped and the next one put under consideration. [para] After all of the above the system will process any options found after the last word assigned to the last [term input] to consider. [para] Errors are thrown if we either find more words than [term inputs] to assign to, or encounter an unknown option flag. Note that not having enough words for all required [term inputs] is not an error unless the framework is not allowed to start an interactive shell. In this [term {mini shell}] all parameters are mapped to shell commands taking a single argument, the string value of parameter to assign. Additional five pseudo commands are available to either abort, or commit to the action, or gain help ([cmd .ok], [cmd .run], [cmd .exit], [cmd .cancel], and [cmd .help]). [para] Parameters marked as [term list]-valued also trigger special behaviours. For [term options] the assigned values get accumulated instead of each new value overwriting the last. For [term inputs] only one such parameter can exist, and will be the last of the [term private]. The processor now takes all remaining words and assign them to this parameter. If the list is also optional then options may be processed ahead or not, depending on the chosen decision mode, as described for regular inputs above. [para] Then are the [term boolean] and [term presence] [term options] modifying the handling of flags and flag arguments. The details of this were already explained in section [term Validation] of [term [vset TITLE_DSL_PARAMETER]]. [subsection [vset EXAMPLE_T]] The examples in this section demonstrate how the [term threshold] algorithm assigns a various number of argument words to a specific set of [term inputs], [term optional] and non. [para][example { Parameter | A? | B | C? | D? | E #Required | 2| | 1| 1| --------------+----+---+----+----+---- 2 arguments: | | a | | | b 3 arguments: | a | b | | | c 4 arguments: | a | b | c | | d 5 arguments: | a | b | c | d | e }] 
 1 2 3 4 5 6 7 8  [section {Related Specification Documents}] [list_begin enum] [enum] [term [vset TITLE_DSL]] [enum] [term [vset TITLE_DSL_OFFICER]] [enum] [term [vset TITLE_DSL_PRIVATE]] [enum] [term [vset TITLE_DSL_PARAMETER]] [list_end]   >  1 2 3 4 5 6 7 8 9  [section {Related Specification Documents}] [list_begin enum] [enum] [term [vset TITLE_DSL]] [enum] [term [vset TITLE_DSL_OFFICER]] [enum] [term [vset TITLE_DSL_PRIVATE]] [enum] [term [vset TITLE_DSL_PARAMETER]] [enum] [term [vset TITLE_FLOW]] [list_end]