Eskil

Check-in [69209dc355]
Login

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

Overview
Comment:Put Pref option handling into new option handling framework
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 69209dc35596c247d5b0026c1f6ae67c5cbec0b9
User & Date: peter 2015-11-22 19:09:04.489
Context
2015-11-22
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
2015-11-21
02:52
Rebuilt command line option handling check-in: d432ba22e3 user: peter tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/eskil.tcl.
4158
4159
4160
4161
4162
4163
4164



4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181




4182
















4183
4184
4185







4186
4187
4188
4189
4190
4191
4192
4193
4194
4195









4196
4197
4198
4199




4200


4201
4202
4203
4204
4205
4206
4207
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
  -limit <lines> : Do not process more than <lines> lines.

To list all options matching a prefix, run 'eskil --query prefix'.
In tcsh use this line to get option completion:
complete eskil 'C/-/`eskil --query -`/'}
}




# Helper to validate command line option for color
proc ValidatePdfColor {arg opt} {
    set fail 0
    if {![string is list $arg] || [llength $arg] != 3} {
        set fail 1
    } else {
        foreach val $arg {
            if {![string is double -strict $val] || $val < 0.0 || $val > 1.0} {
                set fail 1
            }
        }
    }
    if {$fail} {
        puts "Argument $opt must be a list of RBG values from 0.0 to 1.0"
        exit
    }
}





















# Option/flag handling helpers
proc initOpts {} {
    set ::eskil(opts) {}







}
# 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 flag  1
        dict set ::eskil(opts,info) $name given 0
        dict set ::eskil(opts,info) $name multi 0
    }
}









# 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 flag  0




    dict set ::eskil(opts,info) $name given 0


    dict set ::eskil(opts,info) $name multi 0
}
# Add a command line option that takes multiple values
proc addMultOpt {name} {
    dict set ::eskil(opts) $name {}
    dict set ::eskil(opts,info) $name flag  0
    dict set ::eskil(opts,info) $name given 0
    dict set ::eskil(opts,info) $name multi 1
}
# List all known options
proc allOpts {{pat *}} {
    return [dict keys $::eskil(opts) $pat]
}
proc optIsFlag {arg} {
    return [dict get $::eskil(opts,info) $arg flag]
}
proc optIsGiven {arg valName} {
    upvar 1 $valName val
    set val [dict get $::eskil(opts) $arg]
    return [dict get $::eskil(opts,info) $arg given]
}
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













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








>
>
>
|
|















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


>
>
>
>
>
>
>





|
|
<


>
>
>
>
>
>
>
>
>



|
>
>
>
>
|
>
>
|




|
<



















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







4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
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
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
  -limit <lines> : Do not process more than <lines> lines.

To list all options matching a prefix, run 'eskil --query prefix'.
In tcsh use this line to get option completion:
complete eskil 'C/-/`eskil --query -`/'}
}

#####################################
# Option/flag handling helpers
#####################################
# Validators
proc optValidatePdfColor {opt arg} {
    set fail 0
    if {![string is list $arg] || [llength $arg] != 3} {
        set fail 1
    } else {
        foreach val $arg {
            if {![string is double -strict $val] || $val < 0.0 || $val > 1.0} {
                set fail 1
            }
        }
    }
    if {$fail} {
        puts "Argument $opt must be a list of RBG values from 0.0 to 1.0"
        exit
    }
}
proc optValidatePositive {opt arg} {
    if {![string is double -strict $arg] || $arg <= 0} {
        puts "Argument $opt must be a positive number"
        exit
    }
}
proc optValidateNatural {opt arg} {
    if {![string is integer -strict $arg] || $arg < 0} {
        puts "Argument $opt must be a natural number"
        exit
    }
}
proc optValidatePaper {opt arg} {
    package require pdf4tcl
    if {[llength [pdf4tcl::getPaperSize $arg]] != 2} {
        puts "Argument $opt must be a valid paper size"
        puts "Valid paper sizes:"
        puts [join [lsort -dictionary [pdf4tcl::getPaperSizeList]] \n]
        exit
    }
}
# Option database setup
proc initOpts {} {
    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)

    dict set ::eskil(opts,info) $name multi 1
}
# List all known options
proc allOpts {{pat *}} {
    return [dict keys $::eskil(opts) $pat]
}
proc optIsFlag {arg} {
    return [dict get $::eskil(opts,info) $arg flag]
}
proc optIsGiven {arg valName} {
    upvar 1 $valName val
    set val [dict get $::eskil(opts) $arg]
    return [dict get $::eskil(opts,info) $arg given]
}
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]
}

4258
4259
4260
4261
4262
4263
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
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
    if {$::eskil(argc) == 0} {
        Init
        return [makeDiffWin]
    }

    # Set up all options info
    initOpts
    addFlags -w -b -noignore
    addFlags -i -nocase -nodigit -nokeyword
    addFlags --help -help





    addFlags -noparse -line -smallblock -block

    addFlags -char -word







    addFlags -dir -clip -patch -conflict -review -table
    addFlags -browse -noempty -nodiff
    addFlags -server -fine -cvs -svn -debug
    addFlags -foreach -close
    addFlags -nonewline -nonewline+ -nocdiff
    addFlags -pluginlist -pluginallow
    # Options that take values
    addOpt   -plugin
    addOpt   -plugininfo
    addOpt   -plugindump
    # These options affect Pref
    addOpt   -pivot
    addOpt   -context







    addMultOpt -prefix
    addMultOpt -preprocess
    addMultOpt -preprocessleft
    addMultOpt -preprocessright
    addOpt   -printHeaderSize
    addOpt   -printCharsPerLine
    addOpt   -printPaper
    addOpt   -printColorChange
    addOpt   -printColorOld
    addOpt   -printColorNew
    addOpt   -printFont
    # These affect opts
    addOpt   -limit
    addOpt   -maxwidth
    addOpt   -o
    addOpt   -a
    addOpt   -sep
    addOpt   -print







<
<

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

|
|








|
|
>
>
>
>
>
>
>




<
<
<
<
<
<
<







4314
4315
4316
4317
4318
4319
4320


4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360







4361
4362
4363
4364
4365
4366
4367
    if {$::eskil(argc) == 0} {
        Init
        return [makeDiffWin]
    }

    # Set up all options info
    initOpts


    addFlags --help -help
    addPrefFlag -w          ignore -w
    addPrefFlag -b          ignore -b 
    addPrefFlag -noignore   ignore " "
    addPrefFlag -noparse    parse 0
    addPrefFlag -line       parse 1
    addPrefFlag -smallblock parse 2
    addPrefFlag -block      parse 3
    addPrefFlag -char       lineparsewords 0
    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
    addOpt   -plugininfo
    addOpt   -plugindump
    # These options affect Pref
    addPrefOpt -pivot             pivot             optValidatePositive
    addPrefOpt -context           context           optValidateNatural
    addPrefOpt -printHeaderSize   printHeaderSize   optValidatePositive
    addPrefOpt -printCharsPerLine printCharsPerLine optValidatePositive
    addPrefOpt -printPaper        printPaper        optValidatePaper
    addPrefOpt -printColorChange  printColorChange  optValidatePdfColor
    addPrefOpt -printColorOld     printColorOld     optValidatePdfColor  
    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
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
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
    set preferedRev "GIT"
    if {[optGet -svn]} {
        set preferedRev "SVN"
    } elseif {[optGet -cvs]} {
        set preferedRev "CVS"
    }

    # TODO: Handle mutually exclusive options in optparsing directly?
    if {[optIsGiven -w arg]} {
        set ::Pref(ignore) "-w"
    } elseif {[optIsGiven -b arg]} {
        set ::Pref(ignore) "-b"
    } elseif {[optIsGiven -noignore arg]} {
        set ::Pref(ignore) " "
    }
    if {[optIsGiven -noparse arg]} {
        set ::Pref(parse) 0
    } elseif {[optIsGiven -line arg]} {
        set ::Pref(parse) 1
    } elseif {[optIsGiven -smallblock arg]} {
        set ::Pref(parse) 2
    } elseif {[optIsGiven -block arg]} {
        set ::Pref(parse) 3
    }
    if {[optIsGiven -char arg]} {
        set ::Pref(lineparsewords) 0
    } elseif {[optIsGiven -word arg]} {
        set ::Pref(lineparsewords) 1
    }

    # These directly correspond to Pref settings
    set apa {
        -printFont printFont
        -context   context
        -i nocase -nocase nocase
        -noempty   noempty
        -nodigit   nodigit
        -nokeyword dir,ignorekey
        -fine      finegrainchunks
    }
    foreach {opt elem} $apa {
        if {[optIsGiven $opt arg]} {
            set ::Pref($elem) $arg
        }
    }

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







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







4448
4449
4450
4451
4452
4453
4454







































4455
4456
4457
4458
4459
4460
4461
    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]} {
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
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
        set opts(mode) "conflict"
        # Conflict implies foreach
        set foreach 1
    }
    if {[optIsGiven -table arg]} {
        set opts(view) "table"
    }
    if {[optIsGiven -printHeaderSize arg]} {
        if {![string is double -strict $arg] || $arg <= 0} {
            puts "Argument -printHeaderSize must be a positive number"
            exit
        }
        set ::Pref(printHeaderSize) $arg
    }
    if {[optIsGiven -printCharsPerLine arg]} {
        if {![string is double -strict $arg] || $arg <= 0} {
            puts "Argument -printCharsPerLine must be a positive number"
            exit
        }
        set ::Pref(printCharsPerLine) $arg
    }
    if {[optIsGiven -printPaper arg]} {
        package require pdf4tcl
        if {[llength [pdf4tcl::getPaperSize $arg]] != 2} {
            puts "Argument -printPaper must be a valid paper size"
            puts "Valid paper sizes:"
            puts [join [lsort -dictionary [pdf4tcl::getPaperSizeList]] \n]
            exit
        }
        set ::Pref(printPaper) $arg
    }
    if {[optIsGiven -printColorChange arg]} {
        ValidatePdfColor $arg -printColorChange
        set ::Pref(printColorChange) $arg
    }
    if {[optIsGiven -printColorOld arg]} {
        ValidatePdfColor $arg -printColorOld
        set ::Pref(printColorNew1) $arg
    }
    if {[optIsGiven -printColorNew arg]} {
        ValidatePdfColor $arg -printColorNew
        set ::Pref(printColorNew2) $arg
    }
    if {[optIsGiven -pivot arg]} {
        if {$arg >= 1} {
            set ::Pref(pivot) $arg
        }
    }
    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} ""







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







4497
4498
4499
4500
4501
4502
4503









































4504
4505
4506
4507
4508
4509
4510
        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} ""