cmdr
Check-in [88c1cb79e5]
Not logged in
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to [email protected]
or submit via the online form by Sep 9.

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Merged work on negative aliases.
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 88c1cb79e53482c5e579594e09119ca8c722c4dd
User & Date: aku 2015-05-12 22:03:55
Context
2015-05-12
22:15
config, color - Bump version numbers, due to their recent changes. check-in: 4f21251865 user: aku tags: trunk
22:04
Updated to trunk (negative aliases) check-in: 93b8d83d4c user: aku tags: vtype-testing
22:03
Merged work on negative aliases. check-in: 88c1cb79e5 user: aku tags: trunk
22:02
Added docs for negative aliases. Closed-Leaf check-in: 21b94c7e50 user: aku tags: neg-aliases
2015-05-11
22:27
Really complete fixes for help testsuite. check-in: 868958ed6d user: aku tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to config.tcl.

1083
1084
1085
1086
1087
1088
1089
1090

1091
1092
1093
1094
1095
1096
1097
		CMDR CONFIG AMBIGUOUS OPTION
	}

	# Now map the fully expanded option name to its handler and
	# let it deal with the remaining things, including retrieval
	# of the option argument (if any), validation, etc.

	[dict get $myoption [lindex $options 0]] process $option $mypq

	return
    }

    method tooMany {} {
	debug.cmdr/config {}
	my raise "wrong#args, too many" \
	    CMDR CONFIG WRONG-ARGS TOO-MANY






|
>







1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
		CMDR CONFIG AMBIGUOUS OPTION
	}

	# Now map the fully expanded option name to its handler and
	# let it deal with the remaining things, including retrieval
	# of the option argument (if any), validation, etc.

	set full [lindex $options 0]
	[dict get $myoption $full] process $full $mypq
	return
    }

    method tooMany {} {
	debug.cmdr/config {}
	my raise "wrong#args, too many" \
	    CMDR CONFIG WRONG-ARGS TOO-MANY

Changes to doc/parts/dsl_para_naming.inc.

43
44
45
46
47
48
49














50
51
52
53
54
If that is not enough for a specific [term option] this command allows
the specification of any number additional flags to be recognized.

[para] Note however that the framework automatically recognizes not
only the specified flag(s), but also all their unique prefixes,
obviating the need for this command in many cases.















[list_end]









>
>
>
>
>
>
>
>
>
>
>
>
>
>





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
If that is not enough for a specific [term option] this command allows
the specification of any number additional flags to be recognized.

[para] Note however that the framework automatically recognizes not
only the specified flag(s), but also all their unique prefixes,
obviating the need for this command in many cases.

[comment {- - -- --- ----- -------- -------------}]
[call [cmd neg-alias] [arg name]]
[call [cmd !alias] [arg name]]

This command applies only to [term boolean] [term option]s. For them it allows
the specification of any number additional flags to be recognized, which are
aliases of its [emph inverted] form, i.e. of [const --no-FOO] for an option [const FOO].

[para] This in contrast to [cmd alias]es, which are for the regular form of the option.

[para] Note further that the framework automatically recognizes not
only the specified flag(s), but also all their unique prefixes,
obviating the need for this command in many cases.

[list_end]



Changes to embedded/man/files/cmdr_dsl_parameter.n.

275
276
277
278
279
280
281




282
283
284
285
286
287
288
...
387
388
389
390
391
392
393













394
395
396
397
398
399
400
.SH NAME
cmdr-spec-dsl-parameter \- Cmdr - Parameter Specification Language
.SH SYNOPSIS
\fBlabel\fR \fItext\fR
.sp
\fBalias\fR \fIname\fR
.sp




\fBno-promotion\fR
.sp
\fBoptional\fR
.sp
\fBtest\fR
.sp
\fBundocumented\fR
................................................................................
\fIParsing\fR phase\&.
If that is not enough for a specific \fIoption\fR this command allows
the specification of any number additional flags to be recognized\&.
.sp
Note however that the framework automatically recognizes not
only the specified flag(s), but also all their unique prefixes,
obviating the need for this command in many cases\&.













.PP
.PP
.SS "GENERAL CONTROL"
.PP
The general handling of a \fIparameter\fR is influenced by
three commands:
.TP






>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>







275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
...
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
.SH NAME
cmdr-spec-dsl-parameter \- Cmdr - Parameter Specification Language
.SH SYNOPSIS
\fBlabel\fR \fItext\fR
.sp
\fBalias\fR \fIname\fR
.sp
\fBneg-alias\fR \fIname\fR
.sp
\fB!alias\fR \fIname\fR
.sp
\fBno-promotion\fR
.sp
\fBoptional\fR
.sp
\fBtest\fR
.sp
\fBundocumented\fR
................................................................................
\fIParsing\fR phase\&.
If that is not enough for a specific \fIoption\fR this command allows
the specification of any number additional flags to be recognized\&.
.sp
Note however that the framework automatically recognizes not
only the specified flag(s), but also all their unique prefixes,
obviating the need for this command in many cases\&.
.TP
\fBneg-alias\fR \fIname\fR
.TP
\fB!alias\fR \fIname\fR
This command applies only to \fIboolean\fR \fIoption\fRs\&. For them it allows
the specification of any number additional flags to be recognized, which are
aliases of its \fIinverted\fR form, i\&.e\&. of \fB--no-FOO\fR for an option \fBFOO\fR\&.
.sp
This in contrast to \fBalias\fRes, which are for the regular form of the option\&.
.sp
Note further that the framework automatically recognizes not
only the specified flag(s), but also all their unique prefixes,
obviating the need for this command in many cases\&.
.PP
.PP
.SS "GENERAL CONTROL"
.PP
The general handling of a \fIparameter\fR is influenced by
three commands:
.TP

Changes to embedded/www/doc/files/cmdr_dsl_parameter.html.

131
132
133
134
135
136
137


138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
...
215
216
217
218
219
220
221










222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
...
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
...
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
...
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
...
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
...
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
...
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
...
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
</ul>
</div>
<div id="synopsis" class="section"><h2><a name="synopsis">Synopsis</a></h2>
<div class="synopsis">
<ul class="syntax">
<li><a href="#1"><b class="cmd">label</b> <i class="arg">text</i></a></li>
<li><a href="#2"><b class="cmd">alias</b> <i class="arg">name</i></a></li>


<li><a href="#3"><b class="cmd">no-promotion</b></a></li>
<li><a href="#4"><b class="cmd">optional</b></a></li>
<li><a href="#5"><b class="cmd">test</b></a></li>
<li><a href="#6"><b class="cmd">undocumented</b></a></li>
<li><a href="#7"><b class="cmd">default</b> <i class="arg">value</i></a></li>
<li><a href="#8"><b class="cmd">generate</b> <i class="arg">cmdprefix</i></a></li>
<li><a href="#9"><b class="cmd">interact</b> <span class="opt">?<i class="arg">prompt</i>?</span></a></li>
<li><a href="#10"><b class="cmd">list</b></a></li>
<li><a href="#11"><b class="cmd">defered</b></a></li>
<li><a href="#12"><b class="cmd">immediate</b></a></li>
<li><a href="#13"><b class="cmd">validate</b> <i class="arg">cmdprefix</i></a></li>
<li><a href="#14"><b class="cmd">presence</b></a></li>
<li><a href="#15"><b class="cmd">when-complete</b> <i class="arg">cmdprefix</i></a></li>
<li><a href="#16"><b class="cmd">when-set</b> <i class="arg">cmdprefix</i></a></li>
</ul>
</div>
</div>
<div id="section1" class="section"><h2><a name="section1">Description</a></h2>
<p>Welcome to the Cmdr project, written by Andreas Kupries.</p>
<p>For availability please read <i class="term"><a href="cmdr_howto_get_sources.html">Cmdr - How To Get The Sources</a></i>.</p>
<p>This document is for users of the cmdr framework. It introduces the
................................................................................
the name of the <i class="term">primary flag</i> recognized during the
<i class="term">Parsing</i> phase.
If that is not enough for a specific <i class="term">option</i> this command allows
the specification of any number additional flags to be recognized.</p>
<p>Note however that the framework automatically recognizes not
only the specified flag(s), but also all their unique prefixes,
obviating the need for this command in many cases.</p></dd>










</dl>
</div>
<div id="subsection2" class="subsection"><h3><a name="subsection2">General control</a></h3>
<p>The general handling of a <i class="term">parameter</i> is influenced by
three commands:</p>
<dl class="definitions">
<dt><a name="3"><b class="cmd">no-promotion</b></a></dt>
<dd><p>When the framework encounters an unknown flag during the
<i class="term">Parsing</i> phase it will not unconditionally throw an error about
it, but first check if the next available <i class="term">input</i>
<i class="term">parameter</i> (if any) could accept the flag string as its value,
per that <i class="term">input</i>'s <i class="term">validation type</i>, and if yes, does so.</p>
<p>This command causes the rejection of such flag strings by this
parameter on general principle, without having to validate it.</p>
<p><em>Note</em> that it is only useful for and applicable to
<i class="term">input</i> <i class="term"><a href="../../index.html#key12">parameters</a></i>.</p></dd>
<dt><a name="4"><b class="cmd">optional</b></a></dt>
<dd><p>This command marks the parameter as <i class="term">optional</i>, i.e. as something
the user may skip on the command line, with the application supplying
sensible defaults (See section <span class="sectref"><a href="#subsection3">Representations</a></span>).
This causes the framework to expend some effort in the <i class="term">Parsing</i>
phase to determine whether an argument word should be assigned to the
parameter, or not.</p>
<p>This setting is only applicable to <i class="term">input</i>s, as
<i class="term">option</i>s are optional by definition, and <i class="term">state</i> is hidden.</p></dd>
<dt><a name="5"><b class="cmd">test</b></a></dt>
<dd><p>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.</p>
<p>More details are explained in section <i class="term">Parsing</i> of
<i class="term"><a href="cmdr_flow.html">Cmdr - Runtime Processing Flow</a></i>.</p></dd>
<dt><a name="6"><b class="cmd">undocumented</b></a></dt>
<dd><p>This command excludes the <i class="term">parameter</i> from the generated help.</p>
<p>Its main use case is the hiding of <i class="term">option</i>s giving an
application developer access to the internals of their application,
something a regular user has no need of, and doesn't have to know
about.</p></dd>
</dl>
</div>
................................................................................
The details of that process are explained in section <span class="sectref"><a href="#subsection4">Validation</a></span>.
However we have cases where the user cannot specify a string
representation (<i class="term">state</i>s), or is allowed to choose not to
(optional <i class="term">input</i>s, <i class="term">option</i>s).
For these cases three specification commands are made available
enabling us to programmatically choose the internal representation.</p>
<dl class="definitions">
<dt><a name="7"><b class="cmd">default</b> <i class="arg">value</i></a></dt>
<dd><p>This command specifies a constant default value for the internal
representation.</p></dd>
<dt><a name="8"><b class="cmd">generate</b> <i class="arg">cmdprefix</i></a></dt>
<dd><p>This command specifies a callback to compute the default internal
representation at runtime. This is useful if the default is something
which cannot be captured as a fixed value. An example would be a
handle to some resource, or a dynamically created object.</p>
<p>The command prefix is invoked with a single argument, the
<b class="package"><a href="cmdr_parameter.html">cmdr::parameter</a></b> instance for which to generate the internal
representation.</p></dd>
................................................................................
below:</p>
<ol class="enumerated">
<li><p>Use the empty string for a <b class="cmd">list</b> parameter.</p></li>
<li><p>Use the default value supplied by the chosen
<i class="term">validation type</i> (See section <span class="sectref"><a href="#subsection4">Validation</a></span>).</p></li>
</ol>
<dl class="definitions">
<dt><a name="9"><b class="cmd">interact</b> <span class="opt">?<i class="arg">prompt</i>?</span></a></dt>
<dd><p>This command actually does not specify an
<i class="term">internal representation</i>, but activates another method for the
user to specify the <i class="term">string representation</i> of the
<i class="term">parameter</i>, outside of the command line.
As such it has priority over either <b class="cmd">default</b> and <b class="cmd">generate</b>,
and can be specified with either. A <i class="term">parameter</i> marked with it
will interactively ask the user for a value if none was specified on
................................................................................
<li><p>After that the <i class="term">internal representation</i> is either the
declared <b class="cmd">default</b> value, or the result of invoking the
<b class="cmd">generate</b> callback.
As <i class="term">internal representation</i>s the resulting values are
<em>not</em> run through the chosen <i class="term">validation type</i>.</p></li>
</ol>
<dl class="definitions">
<dt><a name="10"><b class="cmd">list</b></a></dt>
<dd><p>This command marks the <i class="term">parameter</i> as a list. In other words, its
<i class="term">string</i> and <i class="term">internal representation</i> is actually a list
of such, instead of a single value.
By default all parameters are scalar.</p>
<p>This affects the handling of the parameter by the
<i class="term">Parsing</i> phase, by <b class="cmd">interact</b> above, and the use of the
<i class="term">validation type</i>.
................................................................................
this list-<i class="term">inputs</i> are only allowed as the last <i class="term">parameter</i>
of a <i class="term">private</i>.</p></dd>
</dl>
<p>The last two specification commands dealing with the
representations control <em>when</em> the
<i class="term">internal representation</i> is created.</p>
<dl class="definitions">
<dt><a name="11"><b class="cmd">defered</b></a></dt>
<dd><p>This command marks a <i class="term">parameter</i> as <i class="term">defered</i>, causing its
<i class="term">internal representation</i> to be computed on first access to its
value. This is the default for <i class="term">state</i> parameters.</p></dd>
<dt><a name="12"><b class="cmd">immediate</b></a></dt>
<dd><p>This command marks a <i class="term">parameter</i> as <i class="term">immediate</i>, causing its
<i class="term">internal representation</i> to be computed in the
<i class="term">Completion</i> phase.
This is the default for <i class="term">input</i> and <i class="term">option</i> parameters.</p></dd>
</dl>
</div>
<div id="subsection4" class="subsection"><h3><a name="subsection4">Validation</a></h3>
................................................................................
Cmdr expects all types to support an ensemble of <em>four</em>
methods.
One for the basic validation and transformation of the input, another
for the release of any internal representation so generated, plus two
more for delivery of a default representation and support for command
line completion.</p>
<dl class="definitions">
<dt><a name="13"><b class="cmd">validate</b> <i class="arg">cmdprefix</i></a></dt>
<dd><p>This command specifies a <i class="term">validation type</i> for the
<i class="term">parameter</i>, in the form of a command prefix (or the name of one
of the builtin types, see package <b class="package"><a href="cmdr_validate.html">cmdr::validate</a></b>).
The set of methods this callback has to support, their signatures,
etc. are all explained in <i class="term"><a href="cmdr_vtypes.html">Cmdr - Writing custom validation types</a></i>. This document
contains the implementation of the standard boolean validation type as
an example as well.</p>
................................................................................
<li><p>Use <b class="const">identity</b> if a <b class="cmd">generate</b> callback is specified.</p></li>
<li><p>Use <b class="const">boolean</b>  if no <b class="cmd">default</b> is specified and the parameter is an <i class="term">option</i>.</p></li>
<li><p>Use <b class="const">identity</b> if no <b class="cmd">default</b> is specified and the parameter is an <i class="term">input</i>.</p></li>
<li><p>Use <b class="const">boolean</b>  if the specified <b class="cmd">default</b> value is a Tcl boolean.</p></li>
<li><p>Use <b class="const">integer</b>  if the specified <b class="cmd">default</b> value is a Tcl integer.</p></li>
<li><p>Use <b class="const">identity</b> as fallback of last resort.</p></li>
</ol></dd>
<dt><a name="14"><b class="cmd">presence</b></a></dt>
<dd><p>This command is best discussed as part of the wider area of
<i class="term">boolean</i> <i class="term">option</i>s, i.e. <i class="term">option</i>s with the standard
<i class="term">validation type</i> <b class="const">boolean</b> assigned to them. These have
associated special behaviours, both in the handling of the
specification, and in the <i class="term">Parsing</i> phase.</p>
<p>First, normal boolean options.
They have automatic aliases declared for them, derived from their
................................................................................
system, as complex scripts can be used via procedures or equivalents
(i.e. <b class="cmd">apply</b>).</p>
<p>The two callbacks not yet described are the state-change
callbacks through which the framework can actively drive parts of the
application while processing the command line, whereas normally the
application drives access to parameters through their methods.</p>
<dl class="definitions">
<dt><a name="15"><b class="cmd">when-complete</b> <i class="arg">cmdprefix</i></a></dt>
<dd><p>This command declares the state-change callback to invoke when the
<i class="term">internal representation</i> of the <i class="term">parameter</i> is generated
from the <i class="term">string representation</i>, or the various ways of
getting a default.</p>
<p>The callback is invoked with two arguments, the
<b class="package"><a href="cmdr_parameter.html">cmdr::parameter</a></b> instance of the changed <i class="term">parameter</i>,
and its <i class="term">internal representation</i>, in this order.</p></dd>
<dt><a name="16"><b class="cmd">when-set</b> <i class="arg">cmdprefix</i></a></dt>
<dd><p>This command declares the state-change callback to invoke when the
<i class="term">string representation</i> of the <i class="term">parameter</i> is set during
command line parsing.</p>
<p>The callback is invoked with two arguments, the
<b class="package"><a href="cmdr_parameter.html">cmdr::parameter</a></b> instance of the changed <i class="term">parameter</i>,
and its <i class="term">string representation</i>, in this order.</p></dd>
</dl>






>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|







 







>
>
>
>
>
>
>
>
>
>






|









|








|





|







 







|


|







 







|







 







|







 







|



|







 







|







 







|







 







|







|







131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
...
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
...
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
...
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
...
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
...
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
...
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
...
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
...
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
</ul>
</div>
<div id="synopsis" class="section"><h2><a name="synopsis">Synopsis</a></h2>
<div class="synopsis">
<ul class="syntax">
<li><a href="#1"><b class="cmd">label</b> <i class="arg">text</i></a></li>
<li><a href="#2"><b class="cmd">alias</b> <i class="arg">name</i></a></li>
<li><a href="#3"><b class="cmd">neg-alias</b> <i class="arg">name</i></a></li>
<li><a href="#4"><b class="cmd">!alias</b> <i class="arg">name</i></a></li>
<li><a href="#5"><b class="cmd">no-promotion</b></a></li>
<li><a href="#6"><b class="cmd">optional</b></a></li>
<li><a href="#7"><b class="cmd">test</b></a></li>
<li><a href="#8"><b class="cmd">undocumented</b></a></li>
<li><a href="#9"><b class="cmd">default</b> <i class="arg">value</i></a></li>
<li><a href="#10"><b class="cmd">generate</b> <i class="arg">cmdprefix</i></a></li>
<li><a href="#11"><b class="cmd">interact</b> <span class="opt">?<i class="arg">prompt</i>?</span></a></li>
<li><a href="#12"><b class="cmd">list</b></a></li>
<li><a href="#13"><b class="cmd">defered</b></a></li>
<li><a href="#14"><b class="cmd">immediate</b></a></li>
<li><a href="#15"><b class="cmd">validate</b> <i class="arg">cmdprefix</i></a></li>
<li><a href="#16"><b class="cmd">presence</b></a></li>
<li><a href="#17"><b class="cmd">when-complete</b> <i class="arg">cmdprefix</i></a></li>
<li><a href="#18"><b class="cmd">when-set</b> <i class="arg">cmdprefix</i></a></li>
</ul>
</div>
</div>
<div id="section1" class="section"><h2><a name="section1">Description</a></h2>
<p>Welcome to the Cmdr project, written by Andreas Kupries.</p>
<p>For availability please read <i class="term"><a href="cmdr_howto_get_sources.html">Cmdr - How To Get The Sources</a></i>.</p>
<p>This document is for users of the cmdr framework. It introduces the
................................................................................
the name of the <i class="term">primary flag</i> recognized during the
<i class="term">Parsing</i> phase.
If that is not enough for a specific <i class="term">option</i> this command allows
the specification of any number additional flags to be recognized.</p>
<p>Note however that the framework automatically recognizes not
only the specified flag(s), but also all their unique prefixes,
obviating the need for this command in many cases.</p></dd>
<dt><a name="3"><b class="cmd">neg-alias</b> <i class="arg">name</i></a></dt>
<dd></dd>
<dt><a name="4"><b class="cmd">!alias</b> <i class="arg">name</i></a></dt>
<dd><p>This command applies only to <i class="term">boolean</i> <i class="term">option</i>s. For them it allows
the specification of any number additional flags to be recognized, which are
aliases of its <em>inverted</em> form, i.e. of <b class="const">--no-FOO</b> for an option <b class="const">FOO</b>.</p>
<p>This in contrast to <b class="cmd">alias</b>es, which are for the regular form of the option.</p>
<p>Note further that the framework automatically recognizes not
only the specified flag(s), but also all their unique prefixes,
obviating the need for this command in many cases.</p></dd>
</dl>
</div>
<div id="subsection2" class="subsection"><h3><a name="subsection2">General control</a></h3>
<p>The general handling of a <i class="term">parameter</i> is influenced by
three commands:</p>
<dl class="definitions">
<dt><a name="5"><b class="cmd">no-promotion</b></a></dt>
<dd><p>When the framework encounters an unknown flag during the
<i class="term">Parsing</i> phase it will not unconditionally throw an error about
it, but first check if the next available <i class="term">input</i>
<i class="term">parameter</i> (if any) could accept the flag string as its value,
per that <i class="term">input</i>'s <i class="term">validation type</i>, and if yes, does so.</p>
<p>This command causes the rejection of such flag strings by this
parameter on general principle, without having to validate it.</p>
<p><em>Note</em> that it is only useful for and applicable to
<i class="term">input</i> <i class="term"><a href="../../index.html#key12">parameters</a></i>.</p></dd>
<dt><a name="6"><b class="cmd">optional</b></a></dt>
<dd><p>This command marks the parameter as <i class="term">optional</i>, i.e. as something
the user may skip on the command line, with the application supplying
sensible defaults (See section <span class="sectref"><a href="#subsection3">Representations</a></span>).
This causes the framework to expend some effort in the <i class="term">Parsing</i>
phase to determine whether an argument word should be assigned to the
parameter, or not.</p>
<p>This setting is only applicable to <i class="term">input</i>s, as
<i class="term">option</i>s are optional by definition, and <i class="term">state</i> is hidden.</p></dd>
<dt><a name="7"><b class="cmd">test</b></a></dt>
<dd><p>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.</p>
<p>More details are explained in section <i class="term">Parsing</i> of
<i class="term"><a href="cmdr_flow.html">Cmdr - Runtime Processing Flow</a></i>.</p></dd>
<dt><a name="8"><b class="cmd">undocumented</b></a></dt>
<dd><p>This command excludes the <i class="term">parameter</i> from the generated help.</p>
<p>Its main use case is the hiding of <i class="term">option</i>s giving an
application developer access to the internals of their application,
something a regular user has no need of, and doesn't have to know
about.</p></dd>
</dl>
</div>
................................................................................
The details of that process are explained in section <span class="sectref"><a href="#subsection4">Validation</a></span>.
However we have cases where the user cannot specify a string
representation (<i class="term">state</i>s), or is allowed to choose not to
(optional <i class="term">input</i>s, <i class="term">option</i>s).
For these cases three specification commands are made available
enabling us to programmatically choose the internal representation.</p>
<dl class="definitions">
<dt><a name="9"><b class="cmd">default</b> <i class="arg">value</i></a></dt>
<dd><p>This command specifies a constant default value for the internal
representation.</p></dd>
<dt><a name="10"><b class="cmd">generate</b> <i class="arg">cmdprefix</i></a></dt>
<dd><p>This command specifies a callback to compute the default internal
representation at runtime. This is useful if the default is something
which cannot be captured as a fixed value. An example would be a
handle to some resource, or a dynamically created object.</p>
<p>The command prefix is invoked with a single argument, the
<b class="package"><a href="cmdr_parameter.html">cmdr::parameter</a></b> instance for which to generate the internal
representation.</p></dd>
................................................................................
below:</p>
<ol class="enumerated">
<li><p>Use the empty string for a <b class="cmd">list</b> parameter.</p></li>
<li><p>Use the default value supplied by the chosen
<i class="term">validation type</i> (See section <span class="sectref"><a href="#subsection4">Validation</a></span>).</p></li>
</ol>
<dl class="definitions">
<dt><a name="11"><b class="cmd">interact</b> <span class="opt">?<i class="arg">prompt</i>?</span></a></dt>
<dd><p>This command actually does not specify an
<i class="term">internal representation</i>, but activates another method for the
user to specify the <i class="term">string representation</i> of the
<i class="term">parameter</i>, outside of the command line.
As such it has priority over either <b class="cmd">default</b> and <b class="cmd">generate</b>,
and can be specified with either. A <i class="term">parameter</i> marked with it
will interactively ask the user for a value if none was specified on
................................................................................
<li><p>After that the <i class="term">internal representation</i> is either the
declared <b class="cmd">default</b> value, or the result of invoking the
<b class="cmd">generate</b> callback.
As <i class="term">internal representation</i>s the resulting values are
<em>not</em> run through the chosen <i class="term">validation type</i>.</p></li>
</ol>
<dl class="definitions">
<dt><a name="12"><b class="cmd">list</b></a></dt>
<dd><p>This command marks the <i class="term">parameter</i> as a list. In other words, its
<i class="term">string</i> and <i class="term">internal representation</i> is actually a list
of such, instead of a single value.
By default all parameters are scalar.</p>
<p>This affects the handling of the parameter by the
<i class="term">Parsing</i> phase, by <b class="cmd">interact</b> above, and the use of the
<i class="term">validation type</i>.
................................................................................
this list-<i class="term">inputs</i> are only allowed as the last <i class="term">parameter</i>
of a <i class="term">private</i>.</p></dd>
</dl>
<p>The last two specification commands dealing with the
representations control <em>when</em> the
<i class="term">internal representation</i> is created.</p>
<dl class="definitions">
<dt><a name="13"><b class="cmd">defered</b></a></dt>
<dd><p>This command marks a <i class="term">parameter</i> as <i class="term">defered</i>, causing its
<i class="term">internal representation</i> to be computed on first access to its
value. This is the default for <i class="term">state</i> parameters.</p></dd>
<dt><a name="14"><b class="cmd">immediate</b></a></dt>
<dd><p>This command marks a <i class="term">parameter</i> as <i class="term">immediate</i>, causing its
<i class="term">internal representation</i> to be computed in the
<i class="term">Completion</i> phase.
This is the default for <i class="term">input</i> and <i class="term">option</i> parameters.</p></dd>
</dl>
</div>
<div id="subsection4" class="subsection"><h3><a name="subsection4">Validation</a></h3>
................................................................................
Cmdr expects all types to support an ensemble of <em>four</em>
methods.
One for the basic validation and transformation of the input, another
for the release of any internal representation so generated, plus two
more for delivery of a default representation and support for command
line completion.</p>
<dl class="definitions">
<dt><a name="15"><b class="cmd">validate</b> <i class="arg">cmdprefix</i></a></dt>
<dd><p>This command specifies a <i class="term">validation type</i> for the
<i class="term">parameter</i>, in the form of a command prefix (or the name of one
of the builtin types, see package <b class="package"><a href="cmdr_validate.html">cmdr::validate</a></b>).
The set of methods this callback has to support, their signatures,
etc. are all explained in <i class="term"><a href="cmdr_vtypes.html">Cmdr - Writing custom validation types</a></i>. This document
contains the implementation of the standard boolean validation type as
an example as well.</p>
................................................................................
<li><p>Use <b class="const">identity</b> if a <b class="cmd">generate</b> callback is specified.</p></li>
<li><p>Use <b class="const">boolean</b>  if no <b class="cmd">default</b> is specified and the parameter is an <i class="term">option</i>.</p></li>
<li><p>Use <b class="const">identity</b> if no <b class="cmd">default</b> is specified and the parameter is an <i class="term">input</i>.</p></li>
<li><p>Use <b class="const">boolean</b>  if the specified <b class="cmd">default</b> value is a Tcl boolean.</p></li>
<li><p>Use <b class="const">integer</b>  if the specified <b class="cmd">default</b> value is a Tcl integer.</p></li>
<li><p>Use <b class="const">identity</b> as fallback of last resort.</p></li>
</ol></dd>
<dt><a name="16"><b class="cmd">presence</b></a></dt>
<dd><p>This command is best discussed as part of the wider area of
<i class="term">boolean</i> <i class="term">option</i>s, i.e. <i class="term">option</i>s with the standard
<i class="term">validation type</i> <b class="const">boolean</b> assigned to them. These have
associated special behaviours, both in the handling of the
specification, and in the <i class="term">Parsing</i> phase.</p>
<p>First, normal boolean options.
They have automatic aliases declared for them, derived from their
................................................................................
system, as complex scripts can be used via procedures or equivalents
(i.e. <b class="cmd">apply</b>).</p>
<p>The two callbacks not yet described are the state-change
callbacks through which the framework can actively drive parts of the
application while processing the command line, whereas normally the
application drives access to parameters through their methods.</p>
<dl class="definitions">
<dt><a name="17"><b class="cmd">when-complete</b> <i class="arg">cmdprefix</i></a></dt>
<dd><p>This command declares the state-change callback to invoke when the
<i class="term">internal representation</i> of the <i class="term">parameter</i> is generated
from the <i class="term">string representation</i>, or the various ways of
getting a default.</p>
<p>The callback is invoked with two arguments, the
<b class="package"><a href="cmdr_parameter.html">cmdr::parameter</a></b> instance of the changed <i class="term">parameter</i>,
and its <i class="term">internal representation</i>, in this order.</p></dd>
<dt><a name="18"><b class="cmd">when-set</b> <i class="arg">cmdprefix</i></a></dt>
<dd><p>This command declares the state-change callback to invoke when the
<i class="term">string representation</i> of the <i class="term">parameter</i> is set during
command line parsing.</p>
<p>The callback is invoked with two arguments, the
<b class="package"><a href="cmdr_parameter.html">cmdr::parameter</a></b> instance of the changed <i class="term">parameter</i>,
and its <i class="term">string representation</i>, in this order.</p></dd>
</dl>

Changes to parameter.tcl.

82
83
84
85
86
87
88

89
90
91
92
93
94
95
...
173
174
175
176
177
178
179




180
181
182
183
184
185
186
...
274
275
276
277
278
279
280


281
282
283
284
285
286
287
...
313
314
315
316
317
318
319


320
321
322
323
324
325
326
...
378
379
380
381
382
383
384







385
386
387
388
389
390
391
...
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549














550
551
552
553
554
555
556
...
669
670
671
672
673
674
675

676
677
678
679
680
681
682
...
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
....
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
	my C2_OptionIsOptional
	my C3_StateIsRequired

	set mystopinteraction no ;# specified interaction is not suppressed.
	set myislist       no ;# scalar vs list parameter
	set myisdocumented yes
	set myonlypresence no ;# options only, no argument when true.

	set myhasdefault   no ;# flag for default existence
	set mydefault      {} ;# default value - raw
	set mygenerate     {} ;# generator command prefix
	set myinteractive  no ;# no interactive query of value
	set myprompt       "Enter ${name}: " ;# standard prompt for interaction

	set myvalidate     {} ;# validation command prefix
................................................................................
		primary  {}
		alias    { return "Alias of [my Option $myname]." }
		inverted { return "Complementary alias of [my Option $myname]." }
	    }
	}
	return $mydescription
    }





    method primary {option} {
	return [expr {[dict get $myflags $option] eq "primary"}]
    }

    method flag {} {
	my Option $mylabel
................................................................................
	# generated text as description of the aliases.

	set myflags {}

	# Import the DSL commands to translate the specification.
	link \
	    {alias         Alias} \


	    {default       Default} \
	    {defered       Defered} \
	    {generate      Generate} \
	    {immediate     Immediate} \
	    {interact      Interact} \
	    {label         Label} \
	    {argument      ArgLabel} \
................................................................................
	my C3_StateIsRequired
	my C5_OptionalHasAlternateInput
	my C5_StateHasAlternateInput
	my C6_RequiredArgumentForbiddenDefault
	my C6_RequiredArgumentForbiddenGenerator
	my C6_RequiredArgumentForbiddenInteract
	my C7_DefaultGeneratorConflict



	return
    }

    # # ## ### ##### ######## #############
    ## Utility functionality for easy setup of exclusions and data
    ## propagation
................................................................................
    }

    method Alias {name} {
	my Alias_Option
	dict set myflags [my Option $name] alias
	return
    }








    method Optional {} {
	# Arguments only. Options are already optional, and state
	# parameters must not be.
	my Optional_State  ; # Order of tests is important, enabling us
	my Optional_Option ; # to simplify the guard conditions inside.
	set myisrequired no
................................................................................

    forward C8_PresenceOption \
	my Assert {$myiscmdline && !$myisordered} \
	{Non-option parameter "@" cannot have presence-only}

    forward C9_ForbiddenPresence \
	my Assert {(!$myhasdefault && ![llength $mygenerate] && ![llength $myvalidate]) || !$myonlypresence} \
	{Customized option cannot be presence-only}

    forward C9_PresenceDefaultConflict \
	my Assert {!$myonlypresence} \
	{Presence-only option cannot have custom default value}

    forward C9_PresenceGeneratorConflict \
	my Assert {!$myonlypresence} \
	{Presence-only option cannot have custom generator command}

    forward C9_PresenceValidateConflict \
	my Assert {!$myonlypresence} \
	{Presence-only option cannot have custom validation type}















    # # ## ### ##### ######## #############
    ## Internal: DSL support. Syntax constraints.

    forward Alias_Option \
	my Assert {$myiscmdline && !$myisordered} \
	{Non-option parameter "@" cannot have alias}
................................................................................
	    set alternate [string range $myname 3 end]
	} else {
	    # The primary option is not inverted, make an alias which is.
	    set alternate no-$myname
	}

	dict set myflags [my Option $alternate] inverted

	return
    }

    method Option {name} {
	# Short options (single character) get a single-dash '-'.
	# Long options use a double-dash '--'.
	if {[string length $name] == 1} {
................................................................................
	    # Look for and process boolean special forms.

	    # Insert implied boolean flag value.
	    #
	    # --foo    non-boolean-value ==> --foo YES non-boolean-value
	    # --no-foo non-boolean-value ==> --foo NO  non-boolean-value

	    # Invert meaning of option.
	    # --no-foo YES ==> --foo NO
	    # --no-foo NO  ==> --foo YES

	    # Take implied or explicit value.
	    if {![$queue size] || ![string is boolean -strict [$queue peek]]} {
		set value yes
	    } else {
		# queue size && boolean
		set value [$queue get]
	    }

	    # Invert meaning, if so requested.
	    if {[string match --no-* $flag]} {
		set value [expr {!$value}]
	    }
	} else {
	    # Everything else has no special forms. The option's value
	    # is required here.
	    if {![$queue size]} { config missingOptionValue $flag }
	    set value [$queue get]
................................................................................
    variable myname mylabel myarglabel mydescription \
	myisordered myiscmdline myislist myisrequired \
	myinteractive myprompt mydefault myhasdefault \
	mywhencomplete mywhenset mygenerate myvalidate \
	myflags mythreshold myhasstring mystring \
	myhasvalue myvalue mylocker mystopinteraction \
	myisdocumented myonlypresence myisdefered \
	myisundefined mynopromote

    # # ## ### ##### ######## #############
}

# # ## ### ##### ######## ############# #####################
## Ready
package provide cmdr::parameter 1.4






>







 







>
>
>
>







 







>
>







 







>
>







 







>
>
>
>
>
>
>







 







|



|



|



|
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>







 







|












|







 







|






|
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
...
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
...
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
...
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
...
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
...
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
...
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
...
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
....
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
	my C2_OptionIsOptional
	my C3_StateIsRequired

	set mystopinteraction no ;# specified interaction is not suppressed.
	set myislist       no ;# scalar vs list parameter
	set myisdocumented yes
	set myonlypresence no ;# options only, no argument when true.
	set myhasinverted  no ;# options only, presence of negative aliases.
	set myhasdefault   no ;# flag for default existence
	set mydefault      {} ;# default value - raw
	set mygenerate     {} ;# generator command prefix
	set myinteractive  no ;# no interactive query of value
	set myprompt       "Enter ${name}: " ;# standard prompt for interaction

	set myvalidate     {} ;# validation command prefix
................................................................................
		primary  {}
		alias    { return "Alias of [my Option $myname]." }
		inverted { return "Complementary alias of [my Option $myname]." }
	    }
	}
	return $mydescription
    }

    method flag-type {detail} {
	return [dict get $myflags $detail]
    }

    method primary {option} {
	return [expr {[dict get $myflags $option] eq "primary"}]
    }

    method flag {} {
	my Option $mylabel
................................................................................
	# generated text as description of the aliases.

	set myflags {}

	# Import the DSL commands to translate the specification.
	link \
	    {alias         Alias} \
	    {!alias        NegAlias} \
	    {neg-alias     NegAlias} \
	    {default       Default} \
	    {defered       Defered} \
	    {generate      Generate} \
	    {immediate     Immediate} \
	    {interact      Interact} \
	    {label         Label} \
	    {argument      ArgLabel} \
................................................................................
	my C3_StateIsRequired
	my C5_OptionalHasAlternateInput
	my C5_StateHasAlternateInput
	my C6_RequiredArgumentForbiddenDefault
	my C6_RequiredArgumentForbiddenGenerator
	my C6_RequiredArgumentForbiddenInteract
	my C7_DefaultGeneratorConflict
	my C10_ForbiddenInvertedAlias
	my C11_ForbiddenInvertedAlias

	return
    }

    # # ## ### ##### ######## #############
    ## Utility functionality for easy setup of exclusions and data
    ## propagation
................................................................................
    }

    method Alias {name} {
	my Alias_Option
	dict set myflags [my Option $name] alias
	return
    }

    method NegAlias {name} {
	my Alias_Option
	dict set myflags [my Option $name] inverted
	set myhasinverted yes
	return
    }

    method Optional {} {
	# Arguments only. Options are already optional, and state
	# parameters must not be.
	my Optional_State  ; # Order of tests is important, enabling us
	my Optional_Option ; # to simplify the guard conditions inside.
	set myisrequired no
................................................................................

    forward C8_PresenceOption \
	my Assert {$myiscmdline && !$myisordered} \
	{Non-option parameter "@" cannot have presence-only}

    forward C9_ForbiddenPresence \
	my Assert {(!$myhasdefault && ![llength $mygenerate] && ![llength $myvalidate]) || !$myonlypresence} \
	{Customized option "@" cannot be presence-only}

    forward C9_PresenceDefaultConflict \
	my Assert {!$myonlypresence} \
	{Presence-only option "@" cannot have custom default value}

    forward C9_PresenceGeneratorConflict \
	my Assert {!$myonlypresence} \
	{Presence-only option "@" cannot have custom generator command}

    forward C9_PresenceValidateConflict \
	my Assert {!$myonlypresence} \
	{Presence-only option "@" cannot have custom validation type}

    forward C10_ForbiddenInvertedAlias \
	my Assert {
	    !$myiscmdline || $myisordered ||
	    ($myvalidate eq "::cmdr::validate::boolean") ||
	    !$myhasinverted
	} {Non-boolean option "@" cannot have negated alias}

    forward C11_ForbiddenInvertedAlias \
	my Assert {
	    !$myiscmdline || $myisordered ||
	    !$myonlypresence ||
	    !$myhasinverted
	} {Presence option "@" cannot have negated alias}

    # # ## ### ##### ######## #############
    ## Internal: DSL support. Syntax constraints.

    forward Alias_Option \
	my Assert {$myiscmdline && !$myisordered} \
	{Non-option parameter "@" cannot have alias}
................................................................................
	    set alternate [string range $myname 3 end]
	} else {
	    # The primary option is not inverted, make an alias which is.
	    set alternate no-$myname
	}

	dict set myflags [my Option $alternate] inverted
	set myhasinverted yes
	return
    }

    method Option {name} {
	# Short options (single character) get a single-dash '-'.
	# Long options use a double-dash '--'.
	if {[string length $name] == 1} {
................................................................................
	    # Look for and process boolean special forms.

	    # Insert implied boolean flag value.
	    #
	    # --foo    non-boolean-value ==> --foo YES non-boolean-value
	    # --no-foo non-boolean-value ==> --foo NO  non-boolean-value

	    # Invert meaning of option (inverted aliases, std, and user).
	    # --no-foo YES ==> --foo NO
	    # --no-foo NO  ==> --foo YES

	    # Take implied or explicit value.
	    if {![$queue size] || ![string is boolean -strict [$queue peek]]} {
		set value yes
	    } else {
		# queue size && boolean
		set value [$queue get]
	    }

	    # Invert meaning, if so requested.
	    if {[dict get $myflags $flag] eq "inverted"} {
		set value [expr {!$value}]
	    }
	} else {
	    # Everything else has no special forms. The option's value
	    # is required here.
	    if {![$queue size]} { config missingOptionValue $flag }
	    set value [$queue get]
................................................................................
    variable myname mylabel myarglabel mydescription \
	myisordered myiscmdline myislist myisrequired \
	myinteractive myprompt mydefault myhasdefault \
	mywhencomplete mywhenset mygenerate myvalidate \
	myflags mythreshold myhasstring mystring \
	myhasvalue myvalue mylocker mystopinteraction \
	myisdocumented myonlypresence myisdefered \
	myisundefined mynopromote myhasinverted

    # # ## ### ##### ######## #############
}

# # ## ### ##### ######## ############# #####################
## Ready
package provide cmdr::parameter 1.5

Changes to tests/parameter.tests.

44
45
46
47
48
49
50



51
52
53
54
55
56
57
..
75
76
77
78
79
80
81
































82
83
84
85
86
87










88
89
90
91
92
93
94
...
174
175
176
177
178
179
180


181
182
183
184
185
186
187
...
193
194
195
196
197
198
199

200
201
202
203
204
205
206
...
212
213
214
215
216
217
218

219
220
221
222
223
224
225
...
334
335
336
337
338
339
340

341
342
343
344
345
346
347
...
444
445
446
447
448
449
450


451
452
453
454
455
456
457
...
526
527
528
529
530
531
532


533
534
535
536
537
538
539
...
690
691
692
693
694
695
696

697
698
699
700
701
702
703
...
709
710
711
712
713
714
715

716
717
718
719
720
721
722
...
798
799
800
801
802
803
804


805
806
807
808
809
810
811
        map -A --> (-A)
        map -X --> (-X)
        para (A) {
            description: '-'
            unordered, cmdline, single, optional, silent, immediate
            default: 'no'
            flags [--no-A -A -X]



            ge ()
            va (::cmdr::validate::boolean)
            wd ()
        }
    }
}

................................................................................
        map -A --> (-A)
        map -X --> (-X)
        para (no-A) {
            description: '-'
            unordered, cmdline, single, optional, silent, immediate
            default: 'no'
            flags [--no-A -A -X]
































            ge ()
            va (::cmdr::validate::boolean)
            wd ()
        }
    }
}











# # ## ### ##### ######## ############# #####################
## Parameter DSL: 'default' across parameters (input, option, state)

test cmdr-parameter-2.0 {parameter DSL, default, wrong num args, not enough} -body {
    BadParamSpec input { default }
} -returnCodes error \
................................................................................
        map --no-A --> (--no-A)
        map -A --> (-A)
        para (A) {
            description: '-'
            unordered, cmdline, single, optional, silent, immediate
            default: '0'
            flags [--no-A -A]


            ge ()
            va (::cmdr::validate::boolean)
            wd ()
        }
    }
}

................................................................................
        option (-A) = A
        map -A --> (-A)
        para (A) {
            description: '-'
            unordered, cmdline, single, optional, silent, immediate
            default: '2'
            flags [-A]

            ge ()
            va (::cmdr::validate::integer)
            wd ()
        }
    }
}

................................................................................
        option (-A) = A
        map -A --> (-A)
        para (A) {
            description: '-'
            unordered, cmdline, single, optional, silent, immediate
            default: 'X'
            flags [-A]

            ge ()
            va (::cmdr::validate::identity)
            wd ()
        }
    }
}

................................................................................
        option (-A) = A
        map -A --> (-A)
        para (A) {
            description: '-'
            unordered, cmdline, single, optional, silent, immediate
            no default
            flags [-A]

            ge (G)
            va (::cmdr::validate::identity)
            wd ()
        }
    }
}

................................................................................
        map -A --> (-A)
        para (A) {
            description: '-'
            unordered, cmdline, single, optional, interact, immediate
            default: 'no'
            prompt: 'Enter A: '
            flags [--no-A -A]


            ge ()
            va (::cmdr::validate::boolean)
            wd ()
        }
    }
}

................................................................................
        map --no-A --> (--no-A)
        map -A --> (-A)
        para (A) {
            description: '-'
            unordered, cmdline, splat, optional, silent, immediate
            default: ''
            flags [--no-A -A]


            ge ()
            va (::cmdr::validate::boolean)
            wd ()
        }
    }
}

................................................................................
        option (-A) = A
        map -A --> (-A)
        para (A) {
            description: '-'
            unordered, cmdline, single, optional, silent, immediate
            default: '0'
            flags [-A]

            ge ()
            va (::cmdr::validate::integer)
            wd ()
        }
    }
}

................................................................................
        option (-A) = A
        map -A --> (-A)
        para (A) {
            description: '-'
            unordered, cmdline, single, optional, silent, immediate
            default: ''
            flags [-A]

            ge ()
            va (::cmdr::validate::identity)
            wd ()
        }
    }
}

................................................................................
        map --no-A --> (--no-A)
        map -A --> (-A)
        para (A) {
            description: '-'
            unordered, cmdline, single, optional, silent, immediate
            default: 'no'
            flags [--no-A -A]


            ge ()
            va (::cmdr::validate::boolean)
            wd (X)
        }
    }
}







>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






>
>
>
>
>
>
>
>
>
>







 







>
>







 







>







 







>







 







>







 







>
>







 







>
>







 







>







 







>







 







>
>







44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
..
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
...
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
...
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
...
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
...
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
...
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
...
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
...
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
...
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
...
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
        map -A --> (-A)
        map -X --> (-X)
        para (A) {
            description: '-'
            unordered, cmdline, single, optional, silent, immediate
            default: 'no'
            flags [--no-A -A -X]
                --no-A = inverted
                -A = primary
                -X = alias
            ge ()
            va (::cmdr::validate::boolean)
            wd ()
        }
    }
}

................................................................................
        map -A --> (-A)
        map -X --> (-X)
        para (no-A) {
            description: '-'
            unordered, cmdline, single, optional, silent, immediate
            default: 'no'
            flags [--no-A -A -X]
                --no-A = primary
                -A = inverted
                -X = alias
            ge ()
            va (::cmdr::validate::boolean)
            wd ()
        }
    }
}

test cmdr-parameter-1.6 {parameter DSL, option, negative alias} -body {
    NiceParamSpec option { neg-alias X }
} -result {
    foo bar = {
        description: ''
        option (--no-A) = A
        option (-A) = A
        option (-X) = A
        map --n --> (--no-A)
        map --no --> (--no-A)
        map --no- --> (--no-A)
        map --no-A --> (--no-A)
        map -A --> (-A)
        map -X --> (-X)
        para (A) {
            description: '-'
            unordered, cmdline, single, optional, silent, immediate
            default: 'no'
            flags [--no-A -A -X]
                --no-A = inverted
                -A = primary
                -X = inverted
            ge ()
            va (::cmdr::validate::boolean)
            wd ()
        }
    }
}

test cmdr-parameter-1.7 {parameter DSL, option, non-boolean, negative alias} -body {
    BadParamSpec option { default 2 ; neg-alias X }
} -returnCodes error \
    -result {Non-boolean option "A" cannot have negated alias}

test cmdr-parameter-1.8 {parameter DSL, option, presence, negative alias} -body {
    BadParamSpec option { presence ; neg-alias X }
} -returnCodes error \
    -result {Presence option "A" cannot have negated alias}

# # ## ### ##### ######## ############# #####################
## Parameter DSL: 'default' across parameters (input, option, state)

test cmdr-parameter-2.0 {parameter DSL, default, wrong num args, not enough} -body {
    BadParamSpec input { default }
} -returnCodes error \
................................................................................
        map --no-A --> (--no-A)
        map -A --> (-A)
        para (A) {
            description: '-'
            unordered, cmdline, single, optional, silent, immediate
            default: '0'
            flags [--no-A -A]
                --no-A = inverted
                -A = primary
            ge ()
            va (::cmdr::validate::boolean)
            wd ()
        }
    }
}

................................................................................
        option (-A) = A
        map -A --> (-A)
        para (A) {
            description: '-'
            unordered, cmdline, single, optional, silent, immediate
            default: '2'
            flags [-A]
                -A = primary
            ge ()
            va (::cmdr::validate::integer)
            wd ()
        }
    }
}

................................................................................
        option (-A) = A
        map -A --> (-A)
        para (A) {
            description: '-'
            unordered, cmdline, single, optional, silent, immediate
            default: 'X'
            flags [-A]
                -A = primary
            ge ()
            va (::cmdr::validate::identity)
            wd ()
        }
    }
}

................................................................................
        option (-A) = A
        map -A --> (-A)
        para (A) {
            description: '-'
            unordered, cmdline, single, optional, silent, immediate
            no default
            flags [-A]
                -A = primary
            ge (G)
            va (::cmdr::validate::identity)
            wd ()
        }
    }
}

................................................................................
        map -A --> (-A)
        para (A) {
            description: '-'
            unordered, cmdline, single, optional, interact, immediate
            default: 'no'
            prompt: 'Enter A: '
            flags [--no-A -A]
                --no-A = inverted
                -A = primary
            ge ()
            va (::cmdr::validate::boolean)
            wd ()
        }
    }
}

................................................................................
        map --no-A --> (--no-A)
        map -A --> (-A)
        para (A) {
            description: '-'
            unordered, cmdline, splat, optional, silent, immediate
            default: ''
            flags [--no-A -A]
                --no-A = inverted
                -A = primary
            ge ()
            va (::cmdr::validate::boolean)
            wd ()
        }
    }
}

................................................................................
        option (-A) = A
        map -A --> (-A)
        para (A) {
            description: '-'
            unordered, cmdline, single, optional, silent, immediate
            default: '0'
            flags [-A]
                -A = primary
            ge ()
            va (::cmdr::validate::integer)
            wd ()
        }
    }
}

................................................................................
        option (-A) = A
        map -A --> (-A)
        para (A) {
            description: '-'
            unordered, cmdline, single, optional, silent, immediate
            default: ''
            flags [-A]
                -A = primary
            ge ()
            va (::cmdr::validate::identity)
            wd ()
        }
    }
}

................................................................................
        map --no-A --> (--no-A)
        map -A --> (-A)
        para (A) {
            description: '-'
            unordered, cmdline, single, optional, silent, immediate
            default: 'no'
            flags [--no-A -A]
                --no-A = inverted
                -A = primary
            ge ()
            va (::cmdr::validate::boolean)
            wd (X)
        }
    }
}

Changes to tests/private.tests.

52
53
54
55
56
57
58


59
60
61
62
63
64
65
...
236
237
238
239
240
241
242


243
244
245
246
247
248
249
            wd ()
        }
        para (OPTION) {
            description: 'OPTION-DESC'
            unordered, cmdline, single, optional, silent, immediate
            default: 'no'
            flags [--no-OPTION --OPTION]


            ge ()
            va (::cmdr::validate::boolean)
            wd ()
        }
        para (STATE) {
            description: 'STATE-DESC'
            unordered, hidden, single, required, silent, defered
................................................................................
        map --no-A --> (--no-A)
        map -A --> (-A)
        para (A) {
            description: 'D'
            unordered, cmdline, single, optional, silent, immediate
            default: 'no'
            flags [--no-A -A]


            ge ()
            va (::cmdr::validate::boolean)
            wd ()
        }
    }
}







>
>







 







>
>







52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
...
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
            wd ()
        }
        para (OPTION) {
            description: 'OPTION-DESC'
            unordered, cmdline, single, optional, silent, immediate
            default: 'no'
            flags [--no-OPTION --OPTION]
                --no-OPTION = inverted
                --OPTION = primary
            ge ()
            va (::cmdr::validate::boolean)
            wd ()
        }
        para (STATE) {
            description: 'STATE-DESC'
            unordered, hidden, single, required, silent, defered
................................................................................
        map --no-A --> (--no-A)
        map -A --> (-A)
        para (A) {
            description: 'D'
            unordered, cmdline, single, optional, silent, immediate
            default: 'no'
            flags [--no-A -A]
                --no-A = inverted
                -A = primary
            ge ()
            va (::cmdr::validate::boolean)
            wd ()
        }
    }
}

Changes to tests/runtime.tests.

618
619
620
621
622
623
624
625
626

627










































628
test cmdr-runtime-7.2 {validation errors} -body {
    ParseFailParse {
	input A - { validate integer }
	input B - { validate integer }
    } 1 X
} -returnCodes error \
    -result {Expected an integer for input "B", got "X"}

# # ## ### ##### ######## ############# #####################












































return








>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
test cmdr-runtime-7.2 {validation errors} -body {
    ParseFailParse {
	input A - { validate integer }
	input B - { validate integer }
    } 1 X
} -returnCodes error \
    -result {Expected an integer for input "B", got "X"}

# # ## ### ##### ######## ############# #####################
## Options, negative aliases

test cmdr-runtime-8.0 {options, simple, boolean, special forms II} -body {
    Parse {
	option A -
	option B -
	option C -
	option D -
	option E -
	option F -
	option G - { validate identity }
    } -A -G=X --no-B -G=X -C=1 -D=0 --no-E=1 --no-F=0
} -result {
    A = 'yes' v'1'
    B = '0'   v'0'
    C = '1'   v'1'
    D = '0'   v'0'
    E = '0'   v'0'
    F = '1'   v'1'
    G = 'X'   v'X'
}

test cmdr-runtime-8.1 {options, boolean, aliases} -body {
    Parse {
	option A - { alias     X }
	option B - { neg-alias Y }
    } -X -Y
} -result {
    A = 'yes' v'1'
    B = '0'   v'0'
}

test cmdr-runtime-8.2 {options, boolean, aliases, special forms} -body {
    Parse {
	option A - { alias     X }
	option B - { neg-alias Y }
    } -X=0 -Y=0
} -result {
    A = '0' v'0'
    B = '1' v'1'
}

# # ## ### ##### ######## ############# #####################

return

Changes to tests/support.tcl.

248
249
250
251
252
253
254



255
256
257
258
259
260
261
	    if {[$c threshold] >= 0} {
		lappend result "        mode=threshold [$c threshold]"
	    } else {
		lappend result "        mode=peek+test"
	    }
	}
	lappend result "        flags \[[$c options]\]"



	lappend result "        ge ([$c generator])"
	lappend result "        va ([$c validator])"
	lappend result "        wd ([$c when-complete])"
	lappend result "    \}"
    }

    lappend result "\}"






>
>
>







248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
	    if {[$c threshold] >= 0} {
		lappend result "        mode=threshold [$c threshold]"
	    } else {
		lappend result "        mode=peek+test"
	    }
	}
	lappend result "        flags \[[$c options]\]"
	foreach oname [$c options] {
	    lappend result "            $oname = [$c flag-type $oname]"
	}
	lappend result "        ge ([$c generator])"
	lappend result "        va ([$c validator])"
	lappend result "        wd ([$c when-complete])"
	lappend result "    \}"
    }

    lappend result "\}"