Version 23 of q3cpma

Updated 2022-06-05 19:03:03 by q3cpma
set website    https://git.sr.ht/~q3cpma/ 
set location   France
set email      [email protected]

My miscellaneous Tcl utilities are here and they contain:

  • naproc : proc with named arguments (separated in named optional and positional mandatory; I should probably make a destructuring-bind equivalent, one day)
% util::naproc test {arg1 arg2} {arg3 1 arg4 {hello world}} {
      list $arg1 $arg2 $arg3 $arg4
  }
% test arg1 foo arg2 bar
foo bar 1 {hello world}
% test arg1 foo arg2 bar arg3 zzz
foo bar zzz {hello world}
  • atexit : schedule script executions at exit
% util::atexit add {puts "hello world"}
% util::atexit add {puts [clock format [clock seconds]]}
% util::atexit add {global env; puts "env: $env(HOME)"}
% util::atexit del {puts "hello world"}
% exit
Wed Jul 14 14:27:58 CEST 2021
env: /home/user
  • quasiquote : yet another way to selectively expand variables
% set var1 hello
% set {var 2} world
% set var3 {1 2}
% eval [util::quasiquote var4 foobar var5 {[* 5 5]} var6 {[list 6 6]} {
      puts "`,var1` `,{var 2}` `,var3` `\[+ ,@var3\] = [+ ,@var3]` `,var4` `,@var5` `,@var6`"
% }]
`hello` `world` `{1 2}` `[+ 1 2] = 3` `foobar` `25` `6 6`
  • format_paragraph : like textutil::adjust followed by textutil::indent with terminal markup
% puts [util::format_paragraph {**Lorem __ipsum__ dolor** sit --amet--, consectetur adipiscing elit, sed
do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum} indent 4 width 70]
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
    eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
    ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
    aliquip ex ea commodo consequat. Duis aute irure dolor in
    reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
    pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
    culpa qui officia deserunt mollit anim id est laborum
  • autocli : all-in-one CLI creation handling option parsing and help text creation
% set argv {-opt1 -opt2 foobar myarg}
% set argc 4
% set opts [util::autocli \
    {opt1 {flag "Opt1 description"} opt2 {param default PARAM_NAME "Opt2 description"}} \
    "Program name" \
    "Short description" \
    {{SYNOPSIS1_ARG1 [SYNOPSIS1_ARG2...]} {SYNOPSIS2_ARG1 SYNOPSIS2_ARG2}} \
    {"Long description as a list of indented and formatted paragraphs"
    "    with some **markup**"}]
opt1 1 opt2 foobar
% set argv
foobar
% util::usage stdout
NAME
    Program name - Short description

SYNOPSIS
    Program name [OPTION]... SYNOPSIS1_ARG1 [SYNOPSIS1_ARG2...]
    Program name [OPTION]... SYNOPSIS2_ARG1 SYNOPSIS2_ARG2

DESCRIPTION
    Long description as a list of indented and formatted paragraphs
          with some markup

OPTIONS
    -opt1
        Opt1 description

    -opt2 PARAM_NAME
        Opt2 description
        Defaults to "default".

    -help
        Print this help message and exit.

  • parse : yet another AWK emulation proc
# List all mountable hotplugged disks/partitions
% exec lsblk -nproNAME,TYPE,HOTPLUG,FSTYPE,MOUNTPOINT | awk {$2 ~ /^(part|disk)$/ && $3 == 1 && NF == 4 {print $1}}
/dev/sdd1
/dev/sde
/dev/sde2
/dev/sde1
% util::parse [exec lsblk -nproNAME,TYPE,HOTPLUG,FSTYPE,MOUNTPOINT] {
        {[~ {^(part|disk)$} $2] && $3 == 1 && $NF == 4} {
                lappend RET $1
        }
}
/dev/sdd1 /dev/sde /dev/sde2 /dev/sde1

along with a lot of small stuff:

  • misc: variables (variable with multiple names), ? (ternary), shift (like sh), ipc_fifo, pretty_list (for use in a sentence), every (works with namespaces)
  • filesystem: is_dir_empty, glob_mtime (glob sorted by mtime)
  • functional: lambda, papply, lfilter, lreduce, lreduceip
  • dict: get? (exist + get in one go), assign (assign the dict content to local variables), join, various nested dict additions

Some Tcl based projects:

Other stuff in separate Wiki pages:


Some "problems" I identified during my Tcl journey:

  • Need for a more pinpoint subst, like Lisp quasi-quoting; needed for Tcl style "closures" (cf aforementioned quasiquote proc).
  • Fossil instead Git... let's face it, Git won the VCS war a long time ago, and Fossil more than probably detracts a significative population from contributing (probably even more than something like CVS or subversion).
  • exec: still not fixed (TIP 424 and 259).
  • trace: add a way to trace all/any variables and access to unknown variables, provide the previous value during a write, integrate with dicts and lists (dict trace/ltrace?).
  • socket: lacks a well supported UD sockets library, portable way of specifying timeout?
  • string: add a -dict option to compare (ticket ).
  • FFI: should be in standard library, possibly.
  • binary scan: no way to get the cursor position (ticket ), would like a more FP -inline switch.
  • binary format: option to switch zero padding position to end instead of beginning.
  • namespace ensemble: add extend subcommand.
  • gets: no getdelim equivalent (chan configure -eol?).

Note: mostly inactive as a Tcl programmer since I became infatuated with CL; still using it as a scripting language for its superior string handling, nice dictionary API or event loop.