Wize /
Validation
Search:  

Tcl Validation

Validation simply involves checking Tcl code for syntax, call arguments and types. It is used via

  wize -Wall script.tcl

or (less commonly) by adding

  set ::tcl_warn(level) all

to the top of the main script file.

Wize implements validation using extern in conjunction with types. You can also enable runtime, per-command type-checking.

Checks Performed

Validation performs the following checking actions:

  • All code in proc bodies is compiled, including nested switch/if/while blocks.
  • Syntax error detection such as unbalanced braces or quotes.
  • Check for commands calls before a proc definition or extern.
  • Parameters to all static calls are checked for count (and possibly types).
  • Virtually all calls to builtin commands are validated
  • Detection of missing upvar, variable or global statements.
  • Data access to all static elements in _ array are checked for pre-initialization.
  • A declare statement to allow defining other pre-initialized Array elements.
  • Arguments with types code or expr are compiled.

Tcl Validation

Validation is more challenging in Tcl because of the highly dynamic nature of the language. For example, standard Tcl does not normally compile a proc until it is first invoked. Even then, any sub-eval blocks such as while, if and switch are not compiled until they themselves are actually executed.

While this behavior is acceptable in production, it can make it difficult to detect problems during development.

Wize overcomes this by providing an option (-Wall) that forces Tcl code to compile as it is being sourced. Then, in the resulting compilation phase, extensive checks can be performed to hopefully identify common programming errors.

Errors or warnings are output in a form similar to gcc warning messages. A side benefit of this approach is that Wize can share a common debugger front-end with gdb, enabling simultaneous debugging of both script and C code.

Tk Validation

Validation of Tk code presents a special challenge. This is because Tk widgets are normally created as object-commands. Subcommands are then accessed via the object/widget-path. eg:

  text .t
  .t insert end "ABC"
  .t delete 1.1

Unfortunately, this use of object/path presents the compile phase with no really effective way to check or validate calls. It can also become quite difficult to maintain such code afterwards. Another problem occurs with editing, as command completion of Tk calls (except creation) isn't really feasible. This last is truly vexing as Tk widgets are responsible for the vast majority of all command options in Tcl/Tk.

To address this Wize refactors the Tk widgets to create a Module command defined in namespace ::Tk::Class. eg:

   namespace eval ::Tk::Text {
      namespace ensemble create; # ...
      extern insert {win pos str args} I
      extern delete {win pos args} I
      # ...
   }
   # note: above ensembles get imported from ::Tk to ::
   text .t
   Text insert .t end "ABC"
   Text delete .t 1.1

Code written this way provides Wize with the ability to check all Tk call arguments at compile time. It also allows editors (like Ted) to support argument completion.

See TkScript and Extern Docs for more details.

Tod Validation

Tod (ie. the _ argument) is also validatable by Wize. Dispatch calls are validated by looking up the command from the first argument of the call. This validates local as well as imported calls. Data elements are also validated by verifying that accesses to $() are initialized in the namespace variable "_".

For example, the following will issue warnings:

  namespace eval ::foo {
    variable _
    array set _ { a 1 b 2 }

    proc relay {_ args} {
      upvar $_ {}
      set (c) $(b);  # Warning is issued for var 'c' undefined.
      $_ bar 1;      # Warning issued for proc 'bar' undefined.
    }

    # ...
  }

© 2008 Peter MacDonald

Page last modified on April 15, 2010, at 08:37 AM