Eskil

Check-in [0e1d677660]
Login

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

Overview
Comment:Put opts option handling into new option handling framework
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 0e1d677660c5c79f4df0a0d0829c6bbd1b3fedcc
User & Date: peter 2015-11-22 19:50:50.972
Context
2015-11-22
20:44
Allow plugins to define command line options. check-in: bb6d838de8 user: peter tags: trunk
19:50
Put opts option handling into new option handling framework check-in: 0e1d677660 user: peter tags: trunk
19:09
Put Pref option handling into new option handling framework check-in: 69209dc355 user: peter tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/eskil.tcl.
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
  -preprocessleft <pair> : TBW
  -preprocessright <pair> : TBW

  -r <ver>    : Version info for version control mode.
  -cvs        : Detect CVS first, if multiple version systems are used.
  -svn        : Detect SVN first, if multiple version systems are used.

  -a <file>   : Give anscestor file for three way merge.
  -conflict   : Treat file as a merge conflict file and enter merge
                mode.
  -o <file>   : Specify merge result output file.
  -fine       : Use fine grained chunks. Useful for merging.

  -browse     : Automatically bring up file dialog after starting.
  -server     : Set up Eskil to be controllable from the outside.







|







4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
  -preprocessleft <pair> : TBW
  -preprocessright <pair> : TBW

  -r <ver>    : Version info for version control mode.
  -cvs        : Detect CVS first, if multiple version systems are used.
  -svn        : Detect SVN first, if multiple version systems are used.

  -a <file>   : Give ancestor file for three way merge.
  -conflict   : Treat file as a merge conflict file and enter merge
                mode.
  -o <file>   : Specify merge result output file.
  -fine       : Use fine grained chunks. Useful for merging.

  -browse     : Automatically bring up file dialog after starting.
  -server     : Set up Eskil to be controllable from the outside.
4208
4209
4210
4211
4212
4213
4214


4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233









4234
4235
4236
4237
4238
4239
4240
4241
4242
4243

















4244
4245
4246
4247
4248
4249
4250
    set ::eskil(opts) {}
    set ::eskil(defoptinfo) {
        flag 0
        given 0
        multi 0
        type ""
        validator ""


    } 
}
# Add a command line flag that do not take a value
proc addFlags {args} {
    foreach name $args {
        dict set ::eskil(opts) $name 0
        dict set ::eskil(opts,info) $name $::eskil(defoptinfo)
        dict set ::eskil(opts,info) $name flag  1
    }
}
# Flag that affects Pref
proc addPrefFlag {name elem {value 1}} {
    dict set ::eskil(opts) $name 0
    dict set ::eskil(opts,info) $name $::eskil(defoptinfo)
    dict set ::eskil(opts,info) $name flag  1
    dict set ::eskil(opts,info) $name type Pref
    dict set ::eskil(opts,info) $name "elem" $elem
    dict set ::eskil(opts,info) $name "value" $value
}









# Add a command line option that takes a value
proc addOpt {name {def ""}} {
    dict set ::eskil(opts) $name $def
    dict set ::eskil(opts,info) $name $::eskil(defoptinfo)
}
# Add a command line option that takes a value and stores in Pref
proc addPrefOpt {name elem {validator ""}} {
    dict set ::eskil(opts) $name ""
    dict set ::eskil(opts,info) $name $::eskil(defoptinfo)
    dict set ::eskil(opts,info) $name type Pref

















    dict set ::eskil(opts,info) $name "elem" $elem
    dict set ::eskil(opts,info) $name "validator" $validator
}
# Add a command line option that takes multiple values
proc addMultOpt {name} {
    dict set ::eskil(opts) $name {}
    dict set ::eskil(opts,info) $name $::eskil(defoptinfo)







>
>



















>
>
>
>
>
>
>
>
>










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







4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
    set ::eskil(opts) {}
    set ::eskil(defoptinfo) {
        flag 0
        given 0
        multi 0
        type ""
        validator ""
        filter ""
        sideeffect ""
    } 
}
# Add a command line flag that do not take a value
proc addFlags {args} {
    foreach name $args {
        dict set ::eskil(opts) $name 0
        dict set ::eskil(opts,info) $name $::eskil(defoptinfo)
        dict set ::eskil(opts,info) $name flag  1
    }
}
# Flag that affects Pref
proc addPrefFlag {name elem {value 1}} {
    dict set ::eskil(opts) $name 0
    dict set ::eskil(opts,info) $name $::eskil(defoptinfo)
    dict set ::eskil(opts,info) $name flag  1
    dict set ::eskil(opts,info) $name type Pref
    dict set ::eskil(opts,info) $name "elem" $elem
    dict set ::eskil(opts,info) $name "value" $value
}
# Flag that affects local opts
proc addOptsFlag {name elem {value 1}} {
    dict set ::eskil(opts) $name 0
    dict set ::eskil(opts,info) $name $::eskil(defoptinfo)
    dict set ::eskil(opts,info) $name flag  1
    dict set ::eskil(opts,info) $name type Opts
    dict set ::eskil(opts,info) $name "elem" $elem
    dict set ::eskil(opts,info) $name "value" $value
}
# Add a command line option that takes a value
proc addOpt {name {def ""}} {
    dict set ::eskil(opts) $name $def
    dict set ::eskil(opts,info) $name $::eskil(defoptinfo)
}
# Add a command line option that takes a value and stores in Pref
proc addPrefOpt {name elem {validator ""}} {
    dict set ::eskil(opts) $name ""
    dict set ::eskil(opts,info) $name $::eskil(defoptinfo)
    dict set ::eskil(opts,info) $name type Pref
    dict set ::eskil(opts,info) $name "elem" $elem
    dict set ::eskil(opts,info) $name "validator" $validator
}
# Add a filter command prefix to an Opt
proc addFilter {name cmd} {
    dict set ::eskil(opts,info) $name filter $cmd
}
# Add a sideeffect to an Opt
##nagelfar syntax addSideEffect x c
proc addSideEffect {name script} {
    dict set ::eskil(opts,info) $name sideeffect $script
}
# Add a command line option that takes a value and stores in local opts
proc addOptsOpt {name elem {validator ""}} {
    dict set ::eskil(opts) $name ""
    dict set ::eskil(opts,info) $name $::eskil(defoptinfo)
    dict set ::eskil(opts,info) $name type Opts
    dict set ::eskil(opts,info) $name "elem" $elem
    dict set ::eskil(opts,info) $name "validator" $validator
}
# Add a command line option that takes multiple values
proc addMultOpt {name} {
    dict set ::eskil(opts) $name {}
    dict set ::eskil(opts,info) $name $::eskil(defoptinfo)
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275

4276
4277
4278
4279
4280














4281
4282




4283
4284
4285
4286
4287
4288
4289
}
proc optSet {arg val} {
    if {[dict get $::eskil(opts,info) $arg multi]} {
        dict lappend ::eskil(opts) $arg $val
    } else {
        dict set ::eskil(opts) $arg $val
    }
    switch [dict get $::eskil(opts,info) $arg type] {
        Pref {
            if {[dict exists $::eskil(opts,info) $arg value]} {
                set val [dict get $::eskil(opts,info) $arg value]
            }

            set cmd [dict get $::eskil(opts,info) $arg validator]
            if {$cmd ne ""} {
                # The validator will exit if it fails
                $cmd $arg $val
            }














            set ::Pref([dict get $::eskil(opts,info) $arg elem]) $val
        }




    }
    dict set ::eskil(opts,info) $arg given 1
}
proc optGet {arg} {
    return [dict get $::eskil(opts) $arg]
}








|
<
|
|
|
>
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>


>
>
>
>







4292
4293
4294
4295
4296
4297
4298
4299

4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
}
proc optSet {arg val} {
    if {[dict get $::eskil(opts,info) $arg multi]} {
        dict lappend ::eskil(opts) $arg $val
    } else {
        dict set ::eskil(opts) $arg $val
    }
    # If it is a flag, the value can come from the settings

    if {[dict exists $::eskil(opts,info) $arg value]} {
        set val [dict get $::eskil(opts,info) $arg value]
    }
    # Any validator?
    set cmd [dict get $::eskil(opts,info) $arg validator]
    if {$cmd ne ""} {
        # The validator will exit if it fails
        $cmd $arg $val
    }
    # Any filter?
    set cmd [dict get $::eskil(opts,info) $arg filter]
    if {$cmd ne ""} {
        set val [{*}$cmd $val]
    }
    # Any side effect?
    set cmd [dict get $::eskil(opts,info) $arg sideeffect]
    if {$cmd ne ""} {
        uplevel 1 $cmd
    }

    set type [dict get $::eskil(opts,info) $arg type]
    switch $type {
        Pref {
            set ::Pref([dict get $::eskil(opts,info) $arg elem]) $val
        }
        Opts {
            upvar 1 opts _xx
            set _xx([dict get $::eskil(opts,info) $arg elem]) $val
        }
    }
    dict set ::eskil(opts,info) $arg given 1
}
proc optGet {arg} {
    return [dict get $::eskil(opts) $arg]
}

4330
4331
4332
4333
4334
4335
4336






4337
4338
4339
4340
4341
4342
4343
4344
    addPrefFlag -word       lineparsewords 1
    addPrefFlag -i          nocase
    addPrefFlag -nocase     nocase 
    addPrefFlag -nodigit    nodigit
    addPrefFlag -nokeyword  dir,ignorekey
    addPrefFlag -noempty    noempty
    addPrefFlag -fine       finegrainchunks






    addFlags -dir -clip -patch -conflict -review -table
    addFlags -browse -nodiff
    addFlags -server -cvs -svn -debug
    addFlags -foreach -close
    addFlags -nonewline -nonewline+ -nocdiff
    addFlags -pluginlist -pluginallow
    # Options that take values
    addOpt   -plugin







>
>
>
>
>
>
|







4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
    addPrefFlag -word       lineparsewords 1
    addPrefFlag -i          nocase
    addPrefFlag -nocase     nocase 
    addPrefFlag -nodigit    nodigit
    addPrefFlag -nokeyword  dir,ignorekey
    addPrefFlag -noempty    noempty
    addPrefFlag -fine       finegrainchunks
    addOptsFlag -table      view  table
    addOptsFlag -conflict mode conflict
    # Conflict implies foreach
    addSideEffect -conflicit {
        optSet -foreach 1
    }
    addFlags -dir -clip -patch -review
    addFlags -browse -nodiff
    addFlags -server -cvs -svn -debug
    addFlags -foreach -close
    addFlags -nonewline -nonewline+ -nocdiff
    addFlags -pluginlist -pluginallow
    # Options that take values
    addOpt   -plugin
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364

4365



4366


4367
4368


4369
4370
4371
4372
4373
4374
4375
    addPrefOpt -printColorNew     printColorNew     optValidatePdfColor
    addPrefOpt -printFont         printFont
    addMultOpt -prefix
    addMultOpt -preprocess
    addMultOpt -preprocessleft
    addMultOpt -preprocessright
    # These affect opts
    addOpt   -limit
    addOpt   -maxwidth
    addOpt   -o

    addOpt   -a



    addOpt   -sep


    addOpt   -print
    addOpt   -printpdf ;# Old option


    addMultOpt -r

    # If the first option is "--query", use it to ask about options.
    if {$::eskil(argc) == 2 && [lindex $::eskil(argv) 0] == "--query"} {
        set arg [lindex $::eskil(argv) 1]
        set allOpts [allOpts]
        if {[lsearch -exact $allOpts $arg] < 0} {







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







4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
    addPrefOpt -printColorNew     printColorNew     optValidatePdfColor
    addPrefOpt -printFont         printFont
    addMultOpt -prefix
    addMultOpt -preprocess
    addMultOpt -preprocessleft
    addMultOpt -preprocessright
    # These affect opts
    addOptsOpt -limit    limitlines
    addOptsOpt -maxwidth maxwidth
    addOptsOpt -o mergeFile 
    addFilter  -o [list file join [pwd]]
    addOptsOpt -a ancestorFile
    addFilter  -a [list file join [pwd]]
    # Default is no ignore on three-way merge
    addSideEffect -a { set ::Pref(ignore) " " }
    addOptsOpt -sep separator
    # Handle if separator is given e.g. as '\t'
    addFilter  -sep [list subst -nocommands -novariables]
    addOptsOpt -print    printFile
    addOptsOpt -printpdf printFile ;# Old option
    addSideEffect -print    { set opts(printFileCmd) 1 }
    addSideEffect -printpdf { set opts(printFileCmd) 1 }
    addMultOpt -r

    # If the first option is "--query", use it to ask about options.
    if {$::eskil(argc) == 2 && [lindex $::eskil(argv) 0] == "--query"} {
        set arg [lindex $::eskil(argv) 1]
        set allOpts [allOpts]
        if {[lsearch -exact $allOpts $arg] < 0} {
4420
4421
4422
4423
4424
4425
4426

4427
4428
4429
4430
4431
4432
4433
            # Options with values
            incr i
            set val [lindex $::eskil(argv) $i]
        }
        optSet $arg $val
    }


    if {[optIsGiven -help arg] || [optIsGiven --help arg]} {
        printUsage
        exit
    }

    # All options have been parsed, extract them to where they need to go








>







4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
            # Options with values
            incr i
            set val [lindex $::eskil(argv) $i]
        }
        optSet $arg $val
    }

    # Any help flag given just prints and exits
    if {[optIsGiven -help arg] || [optIsGiven --help arg]} {
        printUsage
        exit
    }

    # All options have been parsed, extract them to where they need to go

4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
    set preferedRev "GIT"
    if {[optGet -svn]} {
        set preferedRev "SVN"
    } elseif {[optGet -cvs]} {
        set preferedRev "CVS"
    }

    # These directly correspond to opts settings
    set apa {
        -limit limitlines
        -maxwidth maxwidth
    }
    foreach {opt elem} $apa {
        if {[optIsGiven $opt arg]} {
            set opts($elem) $arg
        }
    }

    # These directly correspond to ::eskil settings
    set apa {
        -nonewline  ignorenewline 1
        -nonewline+ ignorenewline 2
        -close      autoclose 1
        -debug      debug 1
    }
    foreach {opt elem val} $apa {
        if {[optIsGiven $opt arg]} {
            set ::eskil($elem) $val
        }
    }

    # Options that need individual checking/processing
    if {[optIsGiven -o arg]} {
        set opts(mergeFile) [file join [pwd] $arg]
    }
    if {[optIsGiven -a arg]} {
        set opts(ancestorFile) [file join [pwd] $arg]
        # Default is no ignore on three-way merge
        set ::Pref(ignore) " "
    }
    if {[optIsGiven -sep arg]} {
        # Handle if separator is given e.g. as '\t'
        set opts(separator) [subst -nocommands -novariables $arg]
    }
    if {[optIsGiven -print arg] || [optIsGiven -printpdf arg]} {
        set opts(printFile) [file join [pwd] $arg]
        set opts(printFileCmd) 1
    }
    if {[optIsGiven -conflict arg]} {
        set opts(mode) "conflict"
        # Conflict implies foreach
        set foreach 1
    }
    if {[optIsGiven -table arg]} {
        set opts(view) "table"
    }
    if {[optIsGiven -prefix arg]} {
        foreach apa $arg {
            set RE [string map [list % $apa] {^.*?\m(%\w+).*$}]
            if {$::Pref(nocase)} {
                set RE "(?i)$RE"
            }
            lappend ::Pref(preprocess) $RE {\1} ""







<
<
<
<
<
<
<
<
<
<
<














<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







4509
4510
4511
4512
4513
4514
4515











4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
























4530
4531
4532
4533
4534
4535
4536
    set preferedRev "GIT"
    if {[optGet -svn]} {
        set preferedRev "SVN"
    } elseif {[optGet -cvs]} {
        set preferedRev "CVS"
    }












    # These directly correspond to ::eskil settings
    set apa {
        -nonewline  ignorenewline 1
        -nonewline+ ignorenewline 2
        -close      autoclose 1
        -debug      debug 1
    }
    foreach {opt elem val} $apa {
        if {[optIsGiven $opt arg]} {
            set ::eskil($elem) $val
        }
    }

    # Options that need individual checking/processing
























    if {[optIsGiven -prefix arg]} {
        foreach apa $arg {
            set RE [string map [list % $apa] {^.*?\m(%\w+).*$}]
            if {$::Pref(nocase)} {
                set RE "(?i)$RE"
            }
            lappend ::Pref(preprocess) $RE {\1} ""