cmdr
Check-in [86ce9388c1]
Not logged in

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

Overview
Comment:Design mistake --- Closing --- Extended handling of "fail-unknown-thing" (fut) with hooks allowing this general code to ask for custom messaging. Directly from the parameter, indirectly from the validation type. Whose "validate" method is where "fail-unknown-thing" got called from. Which means that we have a possible alternative solution which does not go through such a convoluted circle: New convenience function, an extension of "fail-unknown-thing" which simply takes the custom message as a parameter. And we can write more functions of this type then, which take ranges, dicts, etc. and operate on these for rendering, or a possible user-choice to fix the bad value. Saving the current state before making a decision --- Trunk went forward with the alternate approach, see [3305575764].
Timelines: family | ancestors | x-fut-acceptable
Files: files | file ages | folders
SHA1: 86ce9388c1a27b495ca30e9c47beb96903895394
User & Date: andreask 2015-06-26 21:58:26.590
Original Comment: Extended handling of "fail-unknown-thing" (fut) with hooks allowing this general code to ask for custom messaging. Directly from the parameter, indirectly from the validation type. Whose "validate" method is where "fail-unknown-thing" got called from. Which means that we have a possible alternate which does not such a convoluted circle: New convenience function, an extension of "fail-unknown-thing" which simply gets the custom message directly as a parameter. And we can do other functions of this type then, which take ranges, dicts, etc. and operate on these for rendering, or a possible user-choice to fix the bad value. Saving the current state before making a decision.
Context
2015-06-26
21:58
Design mistake --- Closing --- Extended handling of "fail-unknown-thing" (fut) with hooks allowing this general code to ask for custom messaging. Directly from the parameter, indirectly from the validation type. Whose "validate" method is where "fail-unknown-thing" got called from. Which means that we have a possible alternative solution which does not go through such a convoluted circle: New convenience function, an extension of "fail-unknown-thing" which simply takes the custom message as a parameter. And we can write more functions of this type then, which take ranges, dicts, etc. and operate on these for rendering, or a possible user-choice to fix the bad value. Saving the current state before making a decision --- Trunk went forward with the alternate approach, see [3305575764]. Closed-Leaf check-in: 86ce9388c1 user: andreask tags: x-fut-acceptable
2015-05-12
22:15
config, color - Bump version numbers, due to their recent changes. check-in: 4f21251865 user: aku tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to parameter.tcl.
808
809
810
811
812
813
814







815
816
817
818
819
820
821
	}

	set myhasstring yes
	my forget
	my RunWhenSetHooks
	return
    }








    method accept {x} {
	debug.cmdr/parameter {}
	try {
	    my ValueRelease [{*}$myvalidate validate [self] $x]
	    # If that was ok it has to be released also!
	    # XXX Or should we maybe immediately cache it for 'value'?







>
>
>
>
>
>
>







808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
	}

	set myhasstring yes
	my forget
	my RunWhenSetHooks
	return
    }

    method acceptable {} {
	debug.cmdr/parameter {}
	# Ask the validation type of the parameter for text about
	# acceptable values.
	return [{*}$myvalidate acceptable [self]]
    }

    method accept {x} {
	debug.cmdr/parameter {}
	try {
	    my ValueRelease [{*}$myvalidate validate [self] $x]
	    # If that was ok it has to be released also!
	    # XXX Or should we maybe immediately cache it for 'value'?
1295
1296
1297
1298
1299
1300
1301
1302
	myisundefined mynopromote myhasinverted

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

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







|
1302
1303
1304
1305
1306
1307
1308
1309
	myisundefined mynopromote myhasinverted

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

# # ## ### ##### ######## ############# #####################
## Ready
package provide cmdr::parameter 1.6
Changes to validate.tcl.
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
debug define cmdr/validate
debug level  cmdr/validate
debug prefix cmdr/validate {[debug caller] | }

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

namespace eval ::cmdr::validate::boolean {
    namespace export default validate complete release
    namespace ensemble create
    namespace import ::cmdr::validate::common::fail
    namespace import ::cmdr::validate::common::complete-enum
}

proc ::cmdr::validate::boolean::release  {p x} { return }
proc ::cmdr::validate::boolean::default  {p}  {
    debug.cmdr/validate {}
    return no
}






proc ::cmdr::validate::boolean::complete {p x} {
    debug.cmdr/validate {} 10
    return [complete-enum {yes no false true on off 0 1} 1 $x]
}

proc ::cmdr::validate::boolean::validate {p x} {







|










>
>
>
>
>







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
debug define cmdr/validate
debug level  cmdr/validate
debug prefix cmdr/validate {[debug caller] | }

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

namespace eval ::cmdr::validate::boolean {
    namespace export default validate complete release acceptable
    namespace ensemble create
    namespace import ::cmdr::validate::common::fail
    namespace import ::cmdr::validate::common::complete-enum
}

proc ::cmdr::validate::boolean::release  {p x} { return }
proc ::cmdr::validate::boolean::default  {p}  {
    debug.cmdr/validate {}
    return no
}

proc ::cmdr::validate::boolean::acceptable {p} {
    debug.cmdr/validate {} 10
    return "Expected one of: yes, no, false, true, on, off, 0, or 1"
}

proc ::cmdr::validate::boolean::complete {p x} {
    debug.cmdr/validate {} 10
    return [complete-enum {yes no false true on off 0 1} 1 $x]
}

proc ::cmdr::validate::boolean::validate {p x} {
132
133
134
135
136
137
138
139
140
141
142





143
144
145
146
147
148
149
    fail $p DOUBLE "a double" $x
}

# # ## ### ##### ######## ############# #####################
## Any double in [0,100]

namespace eval ::cmdr::validate::percent {
    namespace export default validate complete release
    namespace ensemble create
    namespace import ::cmdr::validate::common::fail
}






proc ::cmdr::validate::percent::release  {p x} { return }
proc ::cmdr::validate::percent::default  {p}  {
    debug.cmdr/validate {}
    return 0
}
proc ::cmdr::validate::percent::complete {p x} {







|



>
>
>
>
>







137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
    fail $p DOUBLE "a double" $x
}

# # ## ### ##### ######## ############# #####################
## Any double in [0,100]

namespace eval ::cmdr::validate::percent {
    namespace export default validate complete release acceptable
    namespace ensemble create
    namespace import ::cmdr::validate::common::fail
}

proc ::cmdr::validate::percent::acceptable {p} {
    debug.cmdr/validate {} 10
    return "Expected a value in the range \[0...100\]."
}

proc ::cmdr::validate::percent::release  {p x} { return }
proc ::cmdr::validate::percent::default  {p}  {
    debug.cmdr/validate {}
    return 0
}
proc ::cmdr::validate::percent::complete {p x} {
197
198
199
200
201
202
203
204
205
206
207






208
209
210
211
212
213
214
proc ::cmdr::validate::str::complete {p x} { debug.cmdr/validate {} 10 ; return {} }
proc ::cmdr::validate::str::validate {p x} { debug.cmdr/validate {}    ; return $x }

# # ## ### ##### ######## ############# #####################
## File, existing and readable

namespace eval ::cmdr::validate::rfile {
    namespace export default validate complete release
    namespace ensemble create
    namespace import ::cmdr::validate::common::fail
    namespace import ::cmdr::validate::common::complete-glob






}

proc ::cmdr::validate::rfile::release  {p x} { return }
proc ::cmdr::validate::rfile::default  {p}   { return {} }
proc ::cmdr::validate::rfile::complete {p x} {
    debug.cmdr/validate {} 10
    complete-glob ::cmdr::validate::rfile::Ok $x







|



>
>
>
>
>
>







207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
proc ::cmdr::validate::str::complete {p x} { debug.cmdr/validate {} 10 ; return {} }
proc ::cmdr::validate::str::validate {p x} { debug.cmdr/validate {}    ; return $x }

# # ## ### ##### ######## ############# #####################
## File, existing and readable

namespace eval ::cmdr::validate::rfile {
    namespace export default validate complete release acceptable
    namespace ensemble create
    namespace import ::cmdr::validate::common::fail
    namespace import ::cmdr::validate::common::complete-glob
    namespace import ::cmdr::validate::common::one-path
}

proc ::cmdr::validate::rfile::acceptable {p} {
    debug.cmdr/validate {} 10
    return [one-path "readable file" ::cmdr::validate::rfile::Ok]
}

proc ::cmdr::validate::rfile::release  {p x} { return }
proc ::cmdr::validate::rfile::default  {p}   { return {} }
proc ::cmdr::validate::rfile::complete {p x} {
    debug.cmdr/validate {} 10
    complete-glob ::cmdr::validate::rfile::Ok $x
226
227
228
229
230
231
232
233
234
235
236

237
238





239
240
241
242
243
244
245
    return 1
}

# # ## ### ##### ######## ############# #####################
## File, existing and writable

namespace eval ::cmdr::validate::wfile {
    namespace export default validate complete release
    namespace ensemble create
    namespace import ::cmdr::validate::common::fail
    namespace import ::cmdr::validate::common::complete-glob

    namespace import ::cmdr::validate::common::ok-directory
}






proc ::cmdr::validate::wfile::release  {p x} { return }
proc ::cmdr::validate::wfile::default  {p}   { return {} }
proc ::cmdr::validate::wfile::complete {p x} {
    debug.cmdr/validate {} 10
    complete-glob ::cmdr::validate::wfile::Ok $x
}







|



>


>
>
>
>
>







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
    return 1
}

# # ## ### ##### ######## ############# #####################
## File, existing and writable

namespace eval ::cmdr::validate::wfile {
    namespace export default validate complete release acceptable
    namespace ensemble create
    namespace import ::cmdr::validate::common::fail
    namespace import ::cmdr::validate::common::complete-glob
    namespace import ::cmdr::validate::common::one-path
    namespace import ::cmdr::validate::common::ok-directory
}

proc ::cmdr::validate::wfile::acceptable {p} {
    debug.cmdr/validate {} 10
    return [one-path "writable file" ::cmdr::validate::wfile::Ok]
}

proc ::cmdr::validate::wfile::release  {p x} { return }
proc ::cmdr::validate::wfile::default  {p}   { return {} }
proc ::cmdr::validate::wfile::complete {p x} {
    debug.cmdr/validate {} 10
    complete-glob ::cmdr::validate::wfile::Ok $x
}
261
262
263
264
265
266
267
268
269
270
271

272
273





274
275
276
277
278
279
280
    return 1
}

# # ## ### ##### ######## ############# #####################
## File, existing and read/writable

namespace eval ::cmdr::validate::rwfile {
    namespace export default validate complete release
    namespace ensemble create
    namespace import ::cmdr::validate::common::fail
    namespace import ::cmdr::validate::common::complete-glob

    namespace import ::cmdr::validate::common::ok-directory
}






proc ::cmdr::validate::rwfile::release  {p x} { return }
proc ::cmdr::validate::rwfile::default  {p}   { return {} }
proc ::cmdr::validate::rwfile::complete {p x} {
    debug.cmdr/validate {} 10
    complete-glob ::cmdr::validate::rwfile::Ok $x
}







|



>


>
>
>
>
>







283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
    return 1
}

# # ## ### ##### ######## ############# #####################
## File, existing and read/writable

namespace eval ::cmdr::validate::rwfile {
    namespace export default validate complete release acceptable
    namespace ensemble create
    namespace import ::cmdr::validate::common::fail
    namespace import ::cmdr::validate::common::complete-glob
    namespace import ::cmdr::validate::common::one-path
    namespace import ::cmdr::validate::common::ok-directory
}

proc ::cmdr::validate::rwfile::acceptable {p} {
    debug.cmdr/validate {} 10
    return [one-path "read/writeable file" ::cmdr::validate::rwfile::Ok]
}

proc ::cmdr::validate::rwfile::release  {p x} { return }
proc ::cmdr::validate::rwfile::default  {p}   { return {} }
proc ::cmdr::validate::rwfile::complete {p x} {
    debug.cmdr/validate {} 10
    complete-glob ::cmdr::validate::rwfile::Ok $x
}
297
298
299
300
301
302
303
304
305
306
307






308
309
310
311
312
313
314
    return 1
}

# # ## ### ##### ######## ############# #####################
## Directory, existing and readable.

namespace eval ::cmdr::validate::rdirectory {
    namespace export default validate complete release
    namespace ensemble create
    namespace import ::cmdr::validate::common::fail
    namespace import ::cmdr::validate::common::complete-glob






}

proc ::cmdr::validate::rdirectory::release  {p x} { return }
proc ::cmdr::validate::rdirectory::default  {p}   { return {} }
proc ::cmdr::validate::rdirectory::complete {p x} {
    debug.cmdr/validate {} 10
    complete-glob ::cmdr::validate::rdirectory::Ok $x







|



>
>
>
>
>
>







325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
    return 1
}

# # ## ### ##### ######## ############# #####################
## Directory, existing and readable.

namespace eval ::cmdr::validate::rdirectory {
    namespace export default validate complete release acceptable
    namespace ensemble create
    namespace import ::cmdr::validate::common::fail
    namespace import ::cmdr::validate::common::complete-glob
    namespace import ::cmdr::validate::common::one-path
}

proc ::cmdr::validate::rdirectory::acceptable {p} {
    debug.cmdr/validate {} 10
    return [one-path "readable directory" ::cmdr::validate::rdirectory::Ok]
}

proc ::cmdr::validate::rdirectory::release  {p x} { return }
proc ::cmdr::validate::rdirectory::default  {p}   { return {} }
proc ::cmdr::validate::rdirectory::complete {p x} {
    debug.cmdr/validate {} 10
    complete-glob ::cmdr::validate::rdirectory::Ok $x
327
328
329
330
331
332
333
334
335
336
337

338
339





340
341
342
343
344
345
346
    return 1
}

# # ## ### ##### ######## ############# #####################
## Directory, existing and read/writable.

namespace eval ::cmdr::validate::rwdirectory {
    namespace export default validate complete release
    namespace ensemble create
    namespace import ::cmdr::validate::common::fail
    namespace import ::cmdr::validate::common::complete-glob

    namespace import ::cmdr::validate::common::ok-directory
}






proc ::cmdr::validate::rwdirectory::release  {p x} { return }
proc ::cmdr::validate::rwdirectory::default  {p}   { return {} }
proc ::cmdr::validate::rwdirectory::complete {p x} {
    debug.cmdr/validate {} 10
    complete-glob ::cmdr::validate::rwdirectory::Ok $x
}







|



>


>
>
>
>
>







361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
    return 1
}

# # ## ### ##### ######## ############# #####################
## Directory, existing and read/writable.

namespace eval ::cmdr::validate::rwdirectory {
    namespace export default validate complete release acceptable
    namespace ensemble create
    namespace import ::cmdr::validate::common::fail
    namespace import ::cmdr::validate::common::complete-glob
    namespace import ::cmdr::validate::common::one-path
    namespace import ::cmdr::validate::common::ok-directory
}

proc ::cmdr::validate::rwdirectory::acceptable {p} {
    debug.cmdr/validate {} 10
    return [one-path "read/writable directory" ::cmdr::validate::rwdirectory::Ok]
}

proc ::cmdr::validate::rwdirectory::release  {p x} { return }
proc ::cmdr::validate::rwdirectory::default  {p}   { return {} }
proc ::cmdr::validate::rwdirectory::complete {p x} {
    debug.cmdr/validate {} 10
    complete-glob ::cmdr::validate::rwdirectory::Ok $x
}
364
365
366
367
368
369
370
371
372
373
374






375
376
377
378
379
380
381
    return 1
}

# # ## ### ##### ######## ############# #####################
## Any path, existing and readable.

namespace eval ::cmdr::validate::rpath {
    namespace export default validate complete release
    namespace ensemble create
    namespace import ::cmdr::validate::common::fail
    namespace import ::cmdr::validate::common::complete-glob






}

proc ::cmdr::validate::rpath::release  {p x} { return }
proc ::cmdr::validate::rpath::default  {p}   { return {} }
proc ::cmdr::validate::rpath::complete {p x} {
    debug.cmdr/validate {} 10
    complete-glob ::cmdr::validate::rpath::Ok $x







|



>
>
>
>
>
>







404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
    return 1
}

# # ## ### ##### ######## ############# #####################
## Any path, existing and readable.

namespace eval ::cmdr::validate::rpath {
    namespace export default validate complete release acceptable
    namespace ensemble create
    namespace import ::cmdr::validate::common::fail
    namespace import ::cmdr::validate::common::complete-glob
    namespace import ::cmdr::validate::common::one-path
}

proc ::cmdr::validate::rpath::acceptable {p} {
    debug.cmdr/validate {} 10
    return [one-path "readable path" ::cmdr::validate::rpath::Ok]
}

proc ::cmdr::validate::rpath::release  {p x} { return }
proc ::cmdr::validate::rpath::default  {p}   { return {} }
proc ::cmdr::validate::rpath::complete {p x} {
    debug.cmdr/validate {} 10
    complete-glob ::cmdr::validate::rpath::Ok $x
393
394
395
396
397
398
399
400
401
402
403

404
405





406
407
408
409
410
411
412
    return 1
}

# # ## ### ##### ######## ############# #####################
## Any path, existing and read/writable.

namespace eval ::cmdr::validate::rwpath {
    namespace export default validate complete release
    namespace ensemble create
    namespace import ::cmdr::validate::common::fail
    namespace import ::cmdr::validate::common::complete-glob

    namespace import ::cmdr::validate::common::ok-directory
}






proc ::cmdr::validate::rwpath::release  {p x} { return }
proc ::cmdr::validate::rwpath::default  {p}   { return {} }
proc ::cmdr::validate::rwpath::complete {p x} {
    debug.cmdr/validate {} 10
    complete-glob ::cmdr::validate::rwpath::Ok $x
}







|



>


>
>
>
>
>







439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
    return 1
}

# # ## ### ##### ######## ############# #####################
## Any path, existing and read/writable.

namespace eval ::cmdr::validate::rwpath {
    namespace export default validate complete release acceptable
    namespace ensemble create
    namespace import ::cmdr::validate::common::fail
    namespace import ::cmdr::validate::common::complete-glob
    namespace import ::cmdr::validate::common::one-path
    namespace import ::cmdr::validate::common::ok-directory
}

proc ::cmdr::validate::rwpath::acceptable {p} {
    debug.cmdr/validate {} 10
    return [one-path "read/writable path" ::cmdr::validate::rwpath::Ok]
}

proc ::cmdr::validate::rwpath::release  {p x} { return }
proc ::cmdr::validate::rwpath::default  {p}   { return {} }
proc ::cmdr::validate::rwpath::complete {p x} {
    debug.cmdr/validate {} 10
    complete-glob ::cmdr::validate::rwpath::Ok $x
}
429
430
431
432
433
434
435
436
437
438
439






440
441
442
443
444
445
446
    return 1
}

# # ## ### ##### ######## ############# #####################
## Channel, for existing and readable file. Defaults to stdin.

namespace eval ::cmdr::validate::rchan {
    namespace export default validate complete release
    namespace ensemble create
    namespace import ::cmdr::validate::common::fail
    namespace import ::cmdr::validate::common::complete-glob






}

proc ::cmdr::validate::rchan::release  {p x} {
    if {$x eq "stdin"} return
    close $x
    return
}







|



>
>
>
>
>
>







481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
    return 1
}

# # ## ### ##### ######## ############# #####################
## Channel, for existing and readable file. Defaults to stdin.

namespace eval ::cmdr::validate::rchan {
    namespace export default validate complete release acceptable
    namespace ensemble create
    namespace import ::cmdr::validate::common::fail
    namespace import ::cmdr::validate::common::complete-glob
    namespace import ::cmdr::validate::common::one-path
}

proc ::cmdr::validate::rchan::acceptable {p} {
    debug.cmdr/validate {} 10
    return [one-path "readable file" ::cmdr::validate::rchan::Ok]
}

proc ::cmdr::validate::rchan::release  {p x} {
    if {$x eq "stdin"} return
    close $x
    return
}
462
463
464
465
466
467
468
469
470
471
472

473
474





475
476
477
478
479
480

481
482
483
484
485
486
487
    return 1
}

# # ## ### ##### ######## ############# #####################
## Channel, for existing and writable file. Defaults to stdout.

namespace eval ::cmdr::validate::wchan {
    namespace export default validate complete release
    namespace ensemble create
    namespace import ::cmdr::validate::common::fail
    namespace import ::cmdr::validate::common::complete-glob

    namespace import ::cmdr::validate::common::ok-directory
}






proc ::cmdr::validate::wchan::release  {p x} {
    if {$x eq "stdout"} return
    close $x
    return
}

proc ::cmdr::validate::wchan::default  {p}   { return stdout }
proc ::cmdr::validate::wchan::complete {p x} {
    debug.cmdr/validate {} 10
    complete-glob ::cmdr::validate::wchan::Ok $x
}
proc ::cmdr::validate::wchan::validate {p x} {
    debug.cmdr/validate {}







|



>


>
>
>
>
>






>







520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
    return 1
}

# # ## ### ##### ######## ############# #####################
## Channel, for existing and writable file. Defaults to stdout.

namespace eval ::cmdr::validate::wchan {
    namespace export default validate complete release acceptable
    namespace ensemble create
    namespace import ::cmdr::validate::common::fail
    namespace import ::cmdr::validate::common::complete-glob
    namespace import ::cmdr::validate::common::one-path
    namespace import ::cmdr::validate::common::ok-directory
}

proc ::cmdr::validate::wchan::acceptable {p} {
    debug.cmdr/validate {} 10
    return [one-path "writable file" ::cmdr::validate::wchan::Ok]
}

proc ::cmdr::validate::wchan::release  {p x} {
    if {$x eq "stdout"} return
    close $x
    return
}

proc ::cmdr::validate::wchan::default  {p}   { return stdout }
proc ::cmdr::validate::wchan::complete {p x} {
    debug.cmdr/validate {} 10
    complete-glob ::cmdr::validate::wchan::Ok $x
}
proc ::cmdr::validate::wchan::validate {p x} {
    debug.cmdr/validate {}
501
502
503
504
505
506
507
508
509
510
511

512
513





514
515
516
517
518
519
520
    return 1
}

# # ## ### ##### ######## ############# #####################
## Channel, for existing and read/writable file. No default.

namespace eval ::cmdr::validate::rwchan {
    namespace export default validate complete release
    namespace ensemble create
    namespace import ::cmdr::validate::common::fail
    namespace import ::cmdr::validate::common::complete-glob

    namespace import ::cmdr::validate::common::ok-directory
}






proc ::cmdr::validate::rwchan::release  {p x} { close $x }
proc ::cmdr::validate::rwchan::default  {p}   { return {} }
proc ::cmdr::validate::rwchan::complete {p x} {
    debug.cmdr/validate {} 10
    complete-glob ::cmdr::validate::rwchan::Ok $x
}







|



>


>
>
>
>
>







566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
    return 1
}

# # ## ### ##### ######## ############# #####################
## Channel, for existing and read/writable file. No default.

namespace eval ::cmdr::validate::rwchan {
    namespace export default validate complete release acceptable
    namespace ensemble create
    namespace import ::cmdr::validate::common::fail
    namespace import ::cmdr::validate::common::complete-glob
    namespace import ::cmdr::validate::common::one-path
    namespace import ::cmdr::validate::common::ok-directory
}

proc ::cmdr::validate::rwchan::acceptable {p} {
    debug.cmdr/validate {} 10
    return [one-path "read/writable file" ::cmdr::validate::rwchan::Ok]
}

proc ::cmdr::validate::rwchan::release  {p x} { close $x }
proc ::cmdr::validate::rwchan::default  {p}   { return {} }
proc ::cmdr::validate::rwchan::complete {p x} {
    debug.cmdr/validate {} 10
    complete-glob ::cmdr::validate::rwchan::Ok $x
}
535
536
537
538
539
540
541
542
543
    if {![file readable $path]} {return 0}
    if {![file writable $path]} {return 0}
    return 1
}

# # ## ### ##### ######## ############# #####################
## Ready
package provide cmdr::validate 1.3.1
return







|

606
607
608
609
610
611
612
613
614
    if {![file readable $path]} {return 0}
    if {![file writable $path]} {return 0}
    return 1
}

# # ## ### ##### ######## ############# #####################
## Ready
package provide cmdr::validate 1.4
return
Changes to vcommon.tcl.
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
    namespace ensemble create
}

namespace eval ::cmdr::validate::common {
    namespace export \
	complete-enum complete-glob complete-substr \
	ok-directory lead-in fail fail-unknown-thing \
	fail-known-thing
    namespace ensemble create
}

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

debug define cmdr/validate/common
debug level  cmdr/validate/common







|







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
    namespace ensemble create
}

namespace eval ::cmdr::validate::common {
    namespace export \
	complete-enum complete-glob complete-substr \
	ok-directory lead-in fail fail-unknown-thing \
	fail-known-thing one-of one-path expected
    namespace ensemble create
}

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

debug define cmdr/validate/common
debug level  cmdr/validate/common
65
66
67
68
69
70
71











72


73


74
75
76
77
78
79
80

proc ::cmdr::validate::common::fail-unknown-thing {p code type x {context {}}} {
    # Specific failure for a named thing: Expected existence, found it missing.
    debug.cmdr/validate/common {}

    append msg "Found a problem with [$p type] \"[$p the-name]\":"
    append msg " [lead-in $type] \"$x\" does not exist$context."











    append msg " Please use a different value."





    return -code error -errorcode [list CMDR VALIDATE {*}$code] $msg
}

proc ::cmdr::validate::common::fail-known-thing {p code type x {context {}}} {
    # Specific failure for a named thing: Expected non-existence, found a definition.
    debug.cmdr/validate/common {}








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

>
>







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

proc ::cmdr::validate::common::fail-unknown-thing {p code type x {context {}}} {
    # Specific failure for a named thing: Expected existence, found it missing.
    debug.cmdr/validate/common {}

    append msg "Found a problem with [$p type] \"[$p the-name]\":"
    append msg " [lead-in $type] \"$x\" does not exist$context."

    # Ping the parameter for knowledge of acceptable values and use
    # the information when available. Fall back to a generic text if
    # the parameter doesn't know anything.
    if {[catch {
	set acceptable [$p acceptable]
	# This calls, indirectly, on method 'acceptable' of p's
	# validation type.
    }]} {
	debug.cmdr/validate/common {fail accept: $::errorInfo}

	append msg " Please use a different value."
    } else {
	debug.cmdr/validate/common {accept: $acceptable}

	append msg " " $acceptable
    }
    return -code error -errorcode [list CMDR VALIDATE {*}$code] $msg
}

proc ::cmdr::validate::common::fail-known-thing {p code type x {context {}}} {
    # Specific failure for a named thing: Expected non-existence, found a definition.
    debug.cmdr/validate/common {}

95
96
97
98
99
100
101




































102
103
104
105
106
107
108
    } elseif {[string match {[aeiouAEIOU]*} $type]} {
	set lead {An }
    } else {
	set lead {A }
    }
    return $lead$type
}





































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

proc ::cmdr::validate::common::complete-enum {choices nocase buffer} {
    # As a helper function for command completion printing anything
    # here would mix with the output of linenoise. Do that only on
    # explicit request (level 10).







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







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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
    } elseif {[string match {[aeiouAEIOU]*} $type]} {
	set lead {An }
    } else {
	set lead {A }
    }
    return $lead$type
}

proc ::cmdr::validate::common::one-path {label filter} {
    set matches [complete-glob $filter *]
    if {![llength $matches]} {
	return "No ${label} found here."
    }
    return "Expected one of\n[one-of $matches yes]"
}

proc ::cmdr::validate::common::one-of {enum {multi no}} {
    if {$multi} {
	set n [string length [expr {1+[llength $enum]}]]
	set m {}
	set i 0
	foreach w $enum { incr i ; append m "[format %${n}d $i]. $w\n" }
    } elseif {[llength $enum] < 2} {
	set m "\"[lindex $enum 0]\""
    } else {
	set m {}
	foreach w [lrange $enum 0 end-1] {
	    append m "\"$w\", "
	}
	append m "or \"[lindex $enum end]\""
    }
    return $m
}

proc ::cmdr::validate::common::expected {enum} {
    if {![llength $enum]} {
	return "Nothing acceptable found"
    }
    set multi [expr {[llength $enum] <= 20}]
    set sep [expr {$multi ? "\n" : ": "}]
    set sfx [expr {$multi ? "" : "."}]
    return "Expected one of$sep[one-of $enum $multi]$sfx"
}

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

proc ::cmdr::validate::common::complete-enum {choices nocase buffer} {
    # As a helper function for command completion printing anything
    # here would mix with the output of linenoise. Do that only on
    # explicit request (level 10).
188
189
190
191
192
193
194
195
196
    if {![file isdirectory $path]} {return 0}
    if {![file writable    $path]} {return 0}
    return 1
}

# # ## ### ##### ######## ############# #####################
## Ready
package provide cmdr::validate::common 1.2
return







|

239
240
241
242
243
244
245
246
247
    if {![file isdirectory $path]} {return 0}
    if {![file writable    $path]} {return 0}
    return 1
}

# # ## ### ##### ######## ############# #####################
## Ready
package provide cmdr::validate::common 1.3
return