Sunday, June 15, 2025

Parsing Unstructed Option Value String

In using a Tcl script as a command line call, being able to parse the argument passed to the script is vital. The following snippet shows how to retrieve and assign such values.

line 2

line 3

 

# list of tested options
set opts "-a -b -c -d -e"

##
# parse a string of arguments
##
# arguments:
#    opts    - list of options not in dict format
#    args    - list of options-values to be parsed
# returns:
#    tagged list of option/values pairs as dict
#
proc parse {opts args} {

    set i 0
    foreach item $args {
        if { $item in $opts } { 
            set tmp [string trim $item -]
            incr i
        } else {
            lappend opt($tmp) $item
        }        
    }

    if { $i != [array size opt] } { 
        error -errorinfo "Error: unbalanced list in arguments."
    }

    return [array get opt]
}

The following line will result in an error as no value passed for option -e. The list element -5 will not be mistaken for an option as it is not a member of the valid options list.

parse $opts -a {1 2 3} -b a b c -c 4 -3 -d -5 -e 

In the above example option -a receives a braced list, that is its contents is a single member of a list. The following line is balanced:

parse $opts -a {1 2 3} -b a b c -c 4 -3 -d -5 -e f

After stripping initial dashes, the following tagged list is returned 

d -5 e f a {{1 2 3}} b {a b c} c {4 -3}

The unsorted ordering being the result of maintaining values in the parse procedure as an array, In practice, this will have no impact of the application of the code. 

Comparing Version Numbers

Sometimes it necessary to compare a current version number against a minimum requirement. This simple wrap around the package command shows how to do it. 

VERSION NUMBERS

Version numbers consist of one or more decimal numbers separated by dots, such as 2 or 1.162 or 3.1.13.1. The first number is called the major version number. Larger numbers correspond to later versions of a package, with leftmost numbers having greater significance. For example, version 2.1 is later than 1.3 and version 3.4.6 is later than 3.3.5. Missing fields are equivalent to zeroes: version 1.3 is the same as version 1.3.0 and 1.3.0.0, so it is earlier than 1.3.1 or 1.3.0.2. A later version number is assumed to be upwards compatible with an earlier version number as long as both versions have the same major version number. For example, Tcl scripts written for version 2.3 of a package should work unchanged under versions 2.3.2, 2.4, and 2.5.1. Changes in the major version number signify incompatible changes: if code is written to use version 2.1 of a package, it is not guaranteed to work unmodified with either version 1.7.3 or version 3.1.


 

# https://wiki.tcl-lang.org/page/package+vsatisfies
proc version {ver min} {

    package vcompare $ver $min
    #package vsatisfies $ver $min

}

puts [version 3.22.1 3.23.3] ;# -1 (earlier)
puts [version 3.24.1 3.23.3] ;#  1 (later)
puts [version 3.23.3 3.23.3] ;#  0 (equal)
puts [version 4.33.5 3.23.3] ;#  1 (later)
puts [version 4.23.5 4.34.3] ;# -1 (earlier)