![]() |
![]() |
The Tcl Dev Kit TclChecker helps you find errors in a Tcl script quickly before you run the script. Using the Tcl Dev Kit TclChecker can help you find problems in new scripts, in scripts from older versions of Tcl/Tk, or in scripts that you have ported from another operating system. You can use the Tcl Dev Kit TclChecker to assess the quality of a body of Tcl code or to quickly examine large Tcl files. Tcl Dev Kit TclChecker also warns about potential incompatibilities to help you upgrade applications to the latest releases of Tcl, Tk, and [incr Tcl].
By default, the Tcl Dev Kit TclChecker verifies scripts written for Tcl version 8.4. You can use the Tcl Dev Kit TclChecker with the packages and versions of Tcl, Tk, and [incr Tcl] listed.
|
Tcl |
Tk |
[incr Tcl] |
Expect |
TclX |
|---|---|---|---|---|
|
7.3 |
3.6 |
1.5 |
n/a |
n/a |
|
7.4 |
4.0 |
2.0 |
n/a |
n/a |
|
7.5 |
4.1 |
2.1 |
n/a |
n/a |
|
7.6 |
4.2 |
2.2 |
n/a |
n/a |
|
8.0 |
8.0 |
3.0 |
5.28 |
8.0 |
|
8.1 |
8.1 |
n/a |
5.29 or 5.30 |
8.1 |
|
8.2 |
8.2 |
3.1 |
5.31 |
8.2 |
|
8.3 |
8.3 |
3.1 |
5.32 - 5.38 |
8.2 |
|
8.4 (default) |
8.4 |
n/a |
n/a |
n/a |
Note: Expect command names that "collide" with command names in the Tcl/Tk core (for example, send) can cause the Tcl Dev Kit TclChecker to misinterpret an Expect script, causing it to report syntax errors. To avoid this, use the exp_ prefix for all such ambiguous commands (for example, use exp_send instead of send).
The TclChecker is only available as a command-line tool. To check a file using the Tcl Dev Kit TclChecker, enter tclchecker.tcl (Windows) or tclchecker (Unix), followed by the file name you wish to check. For example:
tclchecker foo.tcl
If your code contains errors or warnings, the Tcl Dev Kit TclChecker provides feedback by default that looks similar to this:
You can specify multiple file names on the same line, for example:
tclchecker foo1.tcl foo2.tcl
To check all the files in a directory, use the asterisk ("*") with the .tcl file extension, for example:
tclchecker *.tcl
If you don't specify any files, tclchecker expects input from standard input.
For other examples of output, see Examples of Output from the Tcl Dev Kit TclChecker.
To change the font size displayed in the TclChecker, use
Ctrl-plus to increase the font size or Ctrl-minus to
decrease the displayed font size. If you are using Windows with a mouse wheel,
you can alternatively press the Ctrl key and then rotate the mouse
wheel to increase or decrease the font size displayed in the TclChecker.
By default, the Tcl Dev Kit TclChecker performs a two-pass scan of your scripts. The first pass accumulates information about user-defined procedures and user-defined [incr Tcl] classes. This information includes:
The second pass uses this information to provide warnings and error messages concerning the usage of the user-defined procedures, including:
The Tcl Dev Kit TclChecker properly handles all variations of user-defined procedures in namespaces.
Note:The Tcl Dev Kit TclChecker does not currently check the following:
Also, if you define a procedure multiple times, the Tcl Dev Kit TclChecker generates a usage error when calling that procedure only if the call fails to match any of procedure definitions. Because of the dynamic nature of procedure definition and redefinition, the Tcl Dev Kit TclChecker can't determine which argument list is currently valid for the given procedure call.
The Tcl Dev Kit TclChecker does not automatically scan scripts that are sourced by your script. Therefore, you must include on the command line all files that define user procedures and classes used by your script.
For a quicker but less comprehensive check of your scripts, you can use the tclchecker -onepass option to force the Tcl Dev Kit TclChecker to perform a one-pass scan of your scripts. A one-pass scan does not check for any of the potential errors or misuses of user-defined procedures and [incr Tcl] classes described above.
You can also use the tclchecker -verbose option to get a list of all commands used by the scripts you specify that are not defined in that collection of scripts. If you don't include the -verbose option, the Tcl Dev Kit TclChecker doesn't warn you about undefined procedures.
The Tcl Dev Kit TclChecker examines your code and displays a message describing each error or potential mistake that it detects. Depending on the type of script that you are checking, you may want to limit the types of problems that it reports rather than see the entire output from the Tcl Dev Kit TclChecker.
Each message generated by the Tcl Dev Kit TclChecker lists the file and the line number where the error or warning occurred, a messageID, a description of the error or warning, and an error indicator, which is a caret ("^") that indicates the code fragment in which the error occurred. The messageID is the word in parentheses just after the file and line number information. It provides information about the type of problem that generated the error or warning, which are listed below. Using Tcl Dev Kit TclChecker you can specify types of errors and warning that you want to suppress, which allows you to focus to more strategic errors or warnings. The Tcl Dev Kit TclChecker provides suggestions, when possible, on ways to fix the problems that it indicates in the error or warning text.
You can limit output in the following ways:
Messages are grouped into two types of errors and four types of warnings.
The Tcl Dev Kit TclChecker generates a parsing error when it encounters commands that cannot be parsed by the Tcl parser, such as a missing curly brace or badly formed list. For example: the following code generates a parsing error because it is missing a quote at the end of the puts statement:
proc foo {} {
puts "hello
}
In cases like this, the Tcl Dev Kit TclChecker attempts to move past the procedure where the parsing error was found, and continue to check additional commands after the parsing error.
The Tcl Dev Kit TclChecker generates a syntax error when it encounters any errors that will cause your script to fail, such as the wrong number of arguments or invalid types or options. For example, the following code generates a syntax error is because the wrong number of arguments are supplied:
set x 3 45
Only commands defined in Tcl, Tk, or [incr Tcl] are checked for syntax errors.
The Tcl Dev Kit TclChecker generates warnings when a command is used that may be nonportable between various platforms.
set file [open $dir/$file
r]
In this example, the file join command should be used so that the correct directory and file separator is used, that is, "\" on Windows.
Upgrade warnings indicate features that have changed in a later version.
namespace foo {
variable bar 0
}
When [incr Tcl] was upgraded to 3.0, it inherited the Tcl namespace command. The syntax of defining a namespace has changed from older versions of [incr Tcl] because of this. With earlier versions of [incr Tcl], correct usage was:
namespace foo {body}
With [incr Tcl] 3.0 and later, correct usage is shown below:
namespace eval foo {body}
The Tcl Dev Kit TclChecker generates a warning when a performance-optimization opportunity is detected. For example: if your code included:
set x [expr $x * $y]
it would generate a performance warning because performance is improved with curly braces, as shown below:
set x [expr {$x * $y}]
The Tcl Dev Kit TclChecker generates a warning when a command is used in a manner that is possibly incorrect but is still syntactically legal. For example, the incr command expects a value and not a reference below:
incr $counter
You can control which types of errors and warnings the Tcl Dev Kit TclChecker lists by specifying one of the -W flags on the command line.
|
Flag |
Description |
|---|---|
|
-W1 |
Display parsing and syntax errors. |
|
-W2 |
Display parsing and syntax errors, and usage warnings. |
|
-W3 |
Display parsing and syntax errors, portability warnings, upgrade warnings, performance warnings, and usage warnings. |
|
-Wall |
Displays all messages and errors. This is the default. |
As an example, the first time you check your script you might want to display only errors but not warnings. You might first run the Tcl Dev Kit TclChecker with the -W1 flag, which only displays parsing and syntax errors, but does not display any warnings. After examining the output from running with the -W1 flag and fixing any errors that were reported, you might run with the -W2 flag to see a variety of additional warnings.
Each warning or error message has an associated messageID. You can filter out the display specific warnings or errors by specifying -suppress to prevent that type of messageID from being displayed. You might want to filter out certain messages because they point out items that do not apply to the script that you are checking, for example: if you are porting a script to only one platform, you do not care whether your script has portability issues.
In the following example, the messageID is "nonPortCmd":
foo:tcl:53 (nonPortCmd) use of non-portable
command
registry values $key
^
You can suppress this type of message by specifying -suppress nonPortCmd on the command line, for example:
tclchecker -suppress nonPortcmd
foo.tcl
Tip: You can suppress multiple messageID types at the same time by specifying -suppress with the multiple instances of messageIDs in quotation marks, for example:
tclchecker -suppress "nonLiteralExpr badOption"
foo.tcl
You can also specify -suppress with the messageID for each instance of the message ID that you want to filter, for example:
tclchecker -suppress nonLiteralExpr -suppress
badOption foo.tcl
For a complete list of all the messageIDs, see Tcl Dev Kit TclChecker Messages.
To provide examples of the Tcl Dev Kit TclChecker output, here is the sample script, foo.tcl, that is checked in the examples that follow:
set $y 3
set x [expr $y + 5]
set x y z
if {$x > 6}
{
puts out "world"
}
proc foo {args bar} {
puts "hello, world"
}
proc p {{a 0} b} {
puts -nonew "hello"
}
You can specify the -verbose argument when you run the Tcl Dev Kit TclChecker. When you specify -verbose, the Tcl Dev Kit TclChecker displays the error information in three lines and the version and summary information when the Tcl Dev Kit TclChecker exits, for example:
tclchecker -verbose foo.tcl
The feedback from the command line with -verbose specified looks similar to this:
scanning: C:/Tcl/jen/foo.tcl
checking: C:/Tcl/jen/foo.tcl
foo.tcl:6 (warnVarRef) variable reference used where variable name expected
set $y 3
^
foo.tcl:7 (warnExpr) use curly braces to avoid double substitution
expr $y + 5
^
foo.tcl:7 (undefinedVar) use of undefined variable "y"
expr $y + 5
^
foo.tcl:7 (warnExpr) use curly braces to avoid double substitution
expr $y + 5
^
foo.tcl:7 (undefinedVar) use of undefined variable "y"
expr $y + 5
^
foo.tcl:8 (numArgs) wrong # args
set x y z
^
foo.tcl:10 (noScript) missing a script after "if"
if {$x > 6}
^
foo.tcl:11 (warnUndefProc) undefined procedure:
puts out "world"
{
^
foo.tcl:15 (argAfterArgs) argument specified after "args"
proc foo {args bar} {
^
foo.tcl:19 (nonDefAfterDef) non-default arg specified after default
proc p {{a 0} b} {
^
Packages Checked | Version
-----------------|--------
blend 1.2
tcl 8.4
tk 8.4
expect 5.38
[incr Tcl] 3.1
oratcl 2.5
sybtcl 3.0
tclCom 1.0
tclDomPro 1.0
tclX 8.2
xmlAct 1.0
xmlGen 1.0
xmlServer 1.0
Number of Errors: 4
Number of Warnings: 6
Commands that were called but never defined:
--------------------------------------------
puts out "world"
You can specify the -quiet argument when you run the Tcl Dev Kit TclChecker. When you specify -quiet, the Tcl Dev Kit TclChecker displays the basic error information on one line with the messageID, instead of the three-line output that includes the code body and the error indicator, for example:
tclchecker -quiet foo.tcl
The output with the -quiet argument appears as follows:
foo.tcl:6 (warnVarRef) variable reference used where variable name expected foo.tcl:7 (warnExpr) use curly braces to avoid double substitution foo.tcl:7 (undefinedVar) use of undefined variable "y" foo.tcl:7 (warnExpr) use curly braces to avoid double substitution foo.tcl:7 (undefinedVar) use of undefined variable "y" foo.tcl:8 (numArgs) wrong # args foo.tcl:10 (noScript) missing a script after "if" foo.tcl:11 (warnUndefProc) undefined procedure: puts out "world" foo.tcl:15 (argAfterArgs) argument specified after "args" foo.tcl:19 (nonDefAfterDef) non-default arg specified after default
To specify a version of Tcl or Tk other than the default, use the -use command line switch. For example, to check a file written for Tcl7.5 and Tk4.1, enter:
tclchecker -use "Tcl7.5" -use "Tk4.1"
foo.tcl
Valid -use arguments are package names followed by a version number. Supported package names are "Tcl", "Tk", "Expect", "ITcl", "Tclx", and other package for which a ".pcx" file is available. Option specifications for unsupported packages are ignored. Packages and Version Numbers lists the versions supported for each package. If you do not specify a version for a package, the Tcl Dev Kit TclChecker uses the first version of the package it locates.
When specifying older versions of Tcl and any extension (including Tk), the versions of Tcl and any specified extension must be compatible, as listed in Packages and Version Numbers. The following example includes incompatible versions and should not be used:
tclchecker -use "Tcl7.5" -use "Tk4.0"
foo.tcl
The correct version pair is:
tclchecker -use "Tcl7.5" -use "Tk4.1"
foo.tcl
The -use option allows a package version specification, and
overrides package require statements in source Tcl code.
For example, -use Tk4.1 will scan against version 4.1 of Tk,
even if the package require statement specifies a different
version of Tk.
Note: The -use command is ignored if a package require statement does not exist. The checker does not load packages it does not require.
The command line in the following example requests -W1 error checking, which includes only parsing and syntax errors:
tclchecker -W1 foo.tcl
The feedback from the command line with -W1 specified looks similar to this:
scanning: C:/Tcl/jen/foo.tcl
checking: C:/Tcl/jen/foo.tcl
foo.tcl:8 (numArgs) wrong # args
set x y z
^
foo.tcl:10 (noScript) missing a script after "if"
if {$x > 6}
^
foo.tcl:15 (argAfterArgs) argument specified after "args"
proc foo {args bar} {
^
foo.tcl:19 (nonDefAfterDef) non-default arg specified after default
proc p {{a 0} b} {
^
The command line in following example requests -W2 error checking, which includes parsing errors, syntax errors, upgrade warnings, and performance warnings.
tclchecker -W2 foo.tcl
The feedback from the command line with -W2 specified looks similar to this:
scanning: C:/Tcl/jen/foo.tcl
checking: C:/Tcl/jen/foo.tcl
foo.tcl:8 (numArgs) wrong # args
set x y z
^
foo.tcl:10 (noScript) missing a script after "if"
if {$x > 6}
^
foo.tcl:15 (argAfterArgs) argument specified after "args"
proc foo {args bar} {
^
foo.tcl:19 (nonDefAfterDef) non-default arg specified after default
proc p {{a 0} b} {
^
The command line in following example requests -W3 error checking, which includes parsing errors, syntax errors, upgrade, portability, and performance warnings.
tclchecker -W3 foo.tcl
The feedback from the command line with -W3 specified looks similar to this:
scanning: C:/Tcl/jen/foo.tcl
checking: C:/Tcl/jen/foo.tcl
foo.tcl:6 (warnVarRef) variable reference used where variable name expected
set $y 3
^
foo.tcl:7 (warnExpr) use curly braces to avoid double substitution
expr $y + 5
^
foo.tcl:7 (undefinedVar) use of undefined variable "y"
expr $y + 5
^
foo.tcl:7 (warnExpr) use curly braces to avoid double substitution
expr $y + 5
^
foo.tcl:7 (undefinedVar) use of undefined variable "y"
expr $y + 5
^
foo.tcl:8 (numArgs) wrong # args
set x y z
^
foo.tcl:10 (noScript) missing a script after "if"
if {$x > 6}
^
foo.tcl:11 (warnUndefProc) undefined procedure:
puts out "world"
{
^
foo.tcl:15 (argAfterArgs) argument specified after "args"
proc foo {args bar} {
^
foo.tcl:19 (nonDefAfterDef) non-default arg specified after default
proc p {{a 0} b} {
^
| Message ID | Category | Message String |
| argAfterArgs | Error | Argument specified after "args" |
| An argument has been specified after the args keyword in a procedure argument list. The args argument is treated like a normal parameter and does not collect the remaining parameters into a single list. | ||
| argsNotDefault | Error | "args" cannot be defaulted |
| The args keyword cannot be initialized to contain a default value. Although the Tcl interpreter does not complain about this usage, the default value is ignored. | ||
| arrayReadAsScalar | Error | Array variable "variable" read as if a scalar |
| You cannot assign an array variable to a scalar variable. The Tcl Dev Kit TclChecker is aware of the internal variables tcl_platform and Tk::priv, and will generate this error when you attempt to assign these variables to a scalar. | ||
| badArrayIndex | Error | invalid array index "index" |
| This error occurs when you try to read from the tcl_platform internal variable with an invalid index key. The tcl_platform variable is initialized at run-time by the system definition, and should not be manually altered. | ||
| badBoolean | Error | Invalid Boolean value |
| The command expects the string to specify a Boolean value. The string can be "1", "0", "true", "false", "yes", "no", "on", or "off" in any unique abbreviation and case. | ||
| badByteNum | Error | Invalid number, should be between 0 and 255 |
| The type should be a integer between 0 and 255. | ||
| badColorFormat | Error | Invalid color name |
The command expects the string to specify a color value.
The string can be any of the following forms:
colorname can be any of the valid textual names for a color
defined in the server's color database file, such as "red" or "PeachPuff".
If the color name is not a Tcl defined color, a warning is flagged stating
that the color may not be portable across all platforms; see
|
||
| badCursor | Error | Invalid cursor spec |
The command expects the string to specify a cursor to use.
The string can take any of the following forms:
If the name form is used, and the name of the cursor is not
defined on all platforms, a warning is flagged stating that the cursor
is not portable; see |
||
| badFloat | Error | Invalid floating-point value |
| The command expects the string to consist of a floating-point number, which is: white space; a sign; a sequence of digits; a decimal point; a sequence of digits; the letter "e"; and a signed decimal exponent. Any of the fields may be omitted, except that the digits either before or after the decimal point must be present and if the "e" is present then it must be followed by the exponent number. | ||
| badIndex | Error | Invalid index: should be integer or "end" |
| The command expects the string to specify an index value. The string can be an integer or "end". | ||
| badIndexExpr | Error | Invalid index: should be integer or "end" or "end-integer" |
| When reading an index, you must specify the exact integer position, or the position relative to the end of the index using the "end" or "end-index_number" strings. | ||
| badInt | Error | Invalid integer |
| The command expects the string to specify an integer value. The string can be optionally signed and optionally preceded by white space. If the first two characters of the string are "0x" then string is expected to be in hexadecimal form; if the first character of string is "0" then the string is expected to be in octal form; otherwise, the string is expected to be in decimal form. | ||
| badKey | Error | Invalid keyword "key " must be: words |
| The command expects the key string to be a key that matches one of the strings in the options list. | ||
| badLevel | Error | Invalid level |
| The command expects the string to be an integer or a "#" character followed by an integer. | ||
| badList | Error | Invalid list: error-info |
| The command expects the string to be a valid Tcl list. The reason the string is not a valid Tcl list is displayed in the message associated with the error. | ||
| badListLength | Error | Invalid list length: Expected % x == y |
| The command expects the string to be a valid Tcl list with a length n satisfying the condition "n % x == y". For example: "n % 2 == 0" is the condition for lists of even length. | ||
| badMathOp | Error | Invalid expr operator: "operator" |
| When working with mathematical expressions, you must use valid operators for the "expr" command. See "expr" in the Tcl Commands Manual section of the ActiveTcl User Guide. | ||
| badMode | Error | Access mode must include either RDONLY, WRONLY, or RDWR |
| When specifying access modes for a Tcl channel, at least one of the three read-write access modes (RDONLY, WRONLY, or RDWR) must be specified with optional modifiers (APPEND, CREAT, EXCL, NOCTTY, NONBLOCK or TRUNC). | ||
| badNatNum | Error | Invalid value "value": must be an integer > 0 |
| The command expects the string to specify an integer greater than zero. The string can be any non-negative integer. | ||
| badOption | Error | Invalid option "option" must be: options |
| The command expects the option string to be an option that matches one of the strings in options. | ||
| badPixel | Error | Invalid pixel value |
| The command expects the string to specify a pixel value. The string must be an integer pixel or floating-point millimeter, optionally followed by one of the following characters: "c", "i", "m", or "p". | ||
| badResource | Error | Invalid resource name |
| The command expects the string to specify a resource value. If the string length is not four characters, an error is flagged. | ||
| badSwitch | Error | Invalid switch: "switch" |
| The command expects the string to be a switch that matches one of the strings in list of switch options. | ||
| badVersion | Error | Invalid version number |
| The command expects a list of strings that specifies a package version. A valid package version string is any number of integers separated by periods ("."), for example, "1.2.3". | ||
| badWholeNum | Error | Bad value "value": must be a non-negative integer |
| The command expects the string to specify a whole value. The string can be any non-negative integer. | ||
| internalError | Error | Internal error: error |
| This message indicates a bug in the Tcl Dev Kit TclChecker. Please file a bug report, including the steps necessary to reproduce the error, at http://bugs.activestate.com/Tcl Dev Kit. | ||
| invalidUsage | Upgrade Error | Invalid usage, use "foo" instead |
| All functions internal to the Tk binding have been moved to the "Tk::" namespace and have been made private. In Tcl 8.4 mode, this error reports use of a command that is now invalid. | ||
| mismatchOptions | Error | The specified options cannot be used in tandem |
| Two or more options were specified that cannot be used at the same time. The command should be re-written to use only one of the switches. This commonly occurs when an overloaded command performs completely different operations based on the switches. | ||
| noExpr | Error | Missing an expression |
Similar to the numArgs message. The Tcl Dev Kit TclChecker
flags this error message when an expression is missing in an if
statement. |
||
| nonDefAfterDef | Error | Non-default arg specified after default |
| A non-defaulted argument has been specified after a defaulted argument in a procedure argument list. Although the Tcl interpreter does not complain about this usage, the default values are ignored. | ||
| nonPortChannel | Non-Portable Warning | Use of a non-portable file descriptor, use "file" instead |
| A channel was specified that is not supported on all platforms. In most cases, this is when "file0", "file1", or "file2" is used instead of "stdin", "stdout", or "stderr". | ||
| nonPortCmd | Non-Portable Warning | Non-portable command |
| A command was specified that is not supported on all platforms. | ||
| nonPortColor | Non-Portable Warning | Non-portable color name |
| A color was specified that is not supported on all platforms. | ||
| nonPortCursor | Non-Portable Warning | Non-portable cursor usage |
| A cursor was specified that is not supported on all platforms. | ||
| nonPortFile | Non-Portable Warning | Use of non-portable file name, use "file join" |
| A file name was specified that is not supported on all platforms. This warning is flagged, then the string is a combination of words, variables, or commands separated by system-specific file separators (for example, "$dir\$file"). Use the file join command to add the system-specific file separators (for example, "[file join $dir $file]"). | ||
| nonPortOption | Non-Portable Warning | Use of non-portable option |
| An option was specified that is not supported on all platforms. Generally, the option has no effect on the systems that do not support this option. | ||
| nonPortVar | Non-Portable Warning | Use of non-portable variable |
| A variable was used that is not supported on all platforms. In most cases, this is when the tcl_precision variable is used. | ||
| nonPublicVar | Non-Public Warning | use of private variable |
| This error indicates that the program is trying to use the contents of the Tk::priv variable. This variable is internal and should not be used. | ||
| noScript | Error | Missing a script after "control" |
Similar to the numArgs message. The Tcl Dev Kit TclChecker
flags this error message when an expression is missing in an if
statement. |
||
| noSwitchArg | Error | Missing argument for switch switch |
| The command was called with a switch that expected an argument. If no argument was given for the switch, this error is flagged. | ||
| numArgs | Error | Wrong # args |
| An incorrect number of arguments were specified for a command. Due to the dynamic nature of Tcl, this error might be flagged unnecessarily. For example, if the command is called within an eval body with variables that will expand to be multiple arguments. The Tcl Dev Kit TclChecker sees only the one argument, but this may expand to match the required number of arguments when the command is evaluated. | ||
| numListElts | Error | Wrong # of list elements |
| Some commands expect lists with a fixed number of elements. This error indicates that an incorrect number of elements has been specified. See the documentation for the specific command in the ActiveTcl User Guide. | ||
| obsoleteCmd | Error | Deprecated usage, use "command" instead |
| The specified command, option or variable does not exist and is no longer supported in the version of the system you are checking. Use the suggested alternative command, option, or variable to upgrade the script. | ||
| parse | Error | Parse error: error-info |
| The Tcl Dev Kit TclChecker could not parse the script completely due to a parsing error. The reason for the parsing error is displayed in the message associated with the error. | ||
| procNumArgs | Error | Wrong # args for the user-defined proc: procName |
| You are using the wrong number of arguments to call the Tcl procedure procName . Compare the number of arguments used to call the procedure to the number of arguments in the definition of procName. | ||
| tooManyFieldArg | Error | Too many fields in argument specifier |
| A defaulted procedure argument has been specified with multiple values. An argument can have only one default value. If the value is to be a list, quotes or curly braces must be used. | ||
| warnBehaviour | Upgrade Warning | Behaviour has changed |
| This warning indicates use of a variable whose behaviour has changed between the current Tcl version and previous versions. | ||
| warnBehaviourCmd | Upgrade Warning | Behaviour of command has changed |
| This warning indicates use of a command whose behaviour has changed between the current Tcl version and previous versions. | ||
| warnDeprecated | Upgrade Warning | Deprecated usage, use "command" instead |
| The specified command, option or variable does not exist and is no longer supported in the version of the system you are checking. Use the suggested alternative command, option or variable to upgrade the script. | ||
| warnExportPat | Warning | Export patterns should not be qualified |
| Each export pattern can contain glob -style special characters, but it must not include any namespace qualifiers. That is, the pattern can only specify commands in the current (exporting) namespace. | ||
| warnExpr | Performance Warning | Use curly braces to avoid double substitution |
| The expr command performs two levels of substitution
on all expressions that are not inside curly braces. To avoid the second
substitution, and to improve the performance of the command, place the
expression inside curly braces.
There are cases where the second level of substitution is required and this warning will not apply. The Tcl Dev Kit TclChecker does not discern between these cases. |
||
| warnExtraClose | Usage Warning | Unmatched closing character |
| A close bracket or close brace without a matching open bracket or open brace was detected. This frequently indicates an error introduced when a subcommand or script is deleted without deleting the final close brace or bracket. | ||
| warnGlobalNsNonsense | Warning | Global into a namespace is undefined |
Using the global command within a
namespace eval is an undefined operation. |
||
| warnGlobalVarColl | Warning | Namespace variable "foo" may collide with global variable of same name |
When writing to the variable via set
it is undetermined if a global or namespace variable is
created. |
||
| warnIfKeyword | Warning | Deprecated usage, use else or elseif |
| When using the if command, it is legal to omit the else and elseif keywords. However, omission of these keywords tends to produce error-prone code; thus, a warning is flagged. | ||
| warnInternalCmd | Warning | Usage of internal command, may change without notice |
| This message indicates that you are using commands internal to an extension. It is safer to use public APIs wherever possible. | ||
| warnNamespacePat | Warning | glob chars in wrong portion of pattern |
| Each namespace pattern is qualified with the name of an exporting namespace and may have glob -style special characters in the command name at the end of the qualified name. The warning is flagged if glob characters appears in a namespace name. | ||
| warnPattern | Warning | Possible unexpected substitution in pattern |
| Glob patterns use brackets to specify a list of characters to match. If brackets are used and the word is not properly quoted, Tcl will interpret this as a subcommand to be evaluated, rather than a pattern. This warning is flagged to avoid possible usage errors of this nature. | ||
| warnReadonlyVar | Warning | Variable is considered read-only |
The Tcl Dev Kit TclChecker is hard-coded to recognize certain
variables as internal to Tcl/Tk. The value of these variables should not
be changed. These variables include:
|
||
| warnRedefine | Usage Warning | userProc1 redefines userProc2 in file fileName on line lineNum |
| A procedure or class is being defined, imported, inherited, or renamed into a scope where a procedure or class of the same name already exists. | ||
| warnReserved | Upgrade Warning | Keyword is reserved for use in version |
| When checking scripts using older versions of Tcl, Tk or [incr Tcl], this warning is flagged if a command is used that does not exist in the systems that you are checking against, but does exist in later versions. This warning helps to prevent scripts from defining commands that will eventually collide with later versions. | ||
| warnShadowVar | Warning | Shadowing a previous definition |
| This usage of the variable may hide or kill a previous definition of the same name. | ||
| warnUndefinedUpvar | Warning | Upvar'd variable "foo" missing in caller scope "proc" |
| The named procedure (in)directly calls the current scope, but is not defining the variable expected by the upvar. | ||
| warnUndefinedVar | Warning | Use of undefined variable: "foo" |
| The named variable is not known in the current scope. | ||
| warnUndefFunc | Warning | Unknown math function: "function" |
| The specified function is not defined as part of the "expr" command. See the "expr" command reference in the ActiveTcl User Guide for a list of valid functions. | ||
| warnUndefProc | Warning | The procedure was called but was never defined |
| The procedure was not defined in any of the files that were specified on the command line of the current invocation of the Tcl Dev Kit TclChecker. The procedure may get defined dynamically or in a file that was not specified on the Tcl Dev Kit TclChecker command line. This warning is triggered only for the first use of the undefined procedure in the files being checked. | ||
| warnUnsupported | Error | Unsupported command, option or variable: use command |
| The specified command, option or variable still exists but is no longer supported. Use the suggested alternative command, option, or variable to upgrade the script. | ||
| warnUpvarNsNonsense | Error | Non-global upvar into a namespace is undefined |
| You cannot import procedure-local variables into a namespace scope. | ||
| warnVarRef | Warning | Variable reference used where variable name expected |
| Some commands expect a variable name for an argument, for example, incr . If the argument is a variable reference, this warning is flagged to report possible usage errors. | ||
| winAlpha | Error | Window name cannot begin with a capital letter |
| The window name for any Tcl widget cannot begin with a capital letter. | ||
| winBeginDot | Error | Window name must begin with "." |
| The path name for any Tcl widget must begin with a period (".") | ||
| winNotNull | Error | Window name cannot be an empty string |
| A window name or path cannot be an empty string. | ||
| Message ID | Category | Message String |
| blt::badIntRange | Error | Invalid integer range, should be an integer between "value1" and "value2" |
| In some cases, legal integer ranges are defined as part of the command. This error indicates that an integer value outside the legal range has been used. | ||
| blt::badSignal | Error | Invalid mnemonic signal |
| The bgexec command has an option "-killsignal" (Unix only), which accepts a valid mnemonic value. See the blt man pages for command specifications. | ||
| blt::badSignalInt | Error | Invalid signal integer, should be between 1 and 32 |
| The bgexec command has an option "-killsignal" (Unix only), which accepts a valid signal integer value. See the blt man pages for command specifications. | ||
| Message ID | Category | Message String |
| coreTcl::badBinaryFmt | Error | Bad format for binary command: "command" |
| This error indicates that the string provided for the binary command's format switch is invalid. See the documentation for the "binary" command in the ActiveTcl User Guide. | ||
| coreTcl::badCharMap | Error | String map list should have an even number of elements |
| The map list must have an even number of elements. | ||
| coreTcl::badFormatFmt | Error | Bad format for format command: "command" |
| This error indicates that the string provided for the format or scan command's format switch is invalid. See the documentation for the "format" or "scan" command in the ActiveTcl User Guide. | ||
| coreTcl::badRegexp | Error | Bad regexp pattern: "pattern" |
| The specified regular expression is not valid. | ||
| coreTcl::badSerialMode | Error | Bad serial mode |
| When using the fconfigure command, if you are using the -mode switch, you must specify a valid -mode string. See "fconfigure" in the ActiveTcl User Guide for information about command switches. | ||
| coreTcl::badTraceOp | Error | Bad operation operation should be one or more of rwu |
| The command expects the trace operation string to be one or more of the following characters: "r", "w", or "u". | ||
| coreTcl::errBadBrktExp | Error | The bracket expression is missing a close bracket |
| The bracket expression is missing a close bracket. Common errors of this type are caused when the closing bracket is interpreted as a character to match on. For example [] and [^] will generate this error because the close bracket is interpreted as a character to match, or not match, respectively. The correct expressions would be: []] and [^]]. | ||
| coreTcl::serverAndPort | Error | Option -myport is not valid for server sockets |
| The socket command specified the -server option and the -myport option on the same command line. These are conflicting options and cannot be used together. | ||
| coreTcl::socketArgOpt | Error | No argument given for "option" option |
| This error message is not used. | ||
| coreTcl::socketAsync | Error | Cannot use -server option and -async option |
| The socket command specified the -server option and the -async option on the same command line. These are conflicting options and cannot be used together. | ||
| coreTcl::socketBadOpt | Error | Invalid option "option", must be -async, -myaddr, -myport or -server |
| This error message is not used. | ||
| coreTcl::socketServer | Error | Cannot use -async option for server sockets |
| The socket command specified the -async option and the -server option on the same command line. These are conflicting options and cannot be used together. | ||
| coreTcl::warnAIPattern | Upgrade Warning | auto_import pattern is used to restrict loading in later versions of Tcl |
| When using the auto_import command, be aware of functionality changes between Tcl 8.4 and earlier versions. | ||
| coreTcl::warnEscapeChar | Upgrade Warning | "\<char>" is a valid escape sequence in later versions of Tcl. |
| The new regular expression package introduced in Tcl 8.1 added many new special character sequences, called "escape characters." When upgrading to 8.1 or later, the escape characters will change the semantics of the expression. To maintain the behavior of previous versions of Tcl, add another backslash before the character. (This warning is displayed only if you specify the -use option with Tcl 8.0 or earlier.) | ||
| coreTcl::warnMemoryCmd | Warning | Memory is debugging command |
The "memory" command is only available when the core is
compiled using the TCL_MEM_DEBUG mode. |
||
| coreTcl::warnNotSpecial | Upgrade Warning | "\<char>" has no meaning. Did you mean "\\<char>" or "<char>"? |
| The backslash character is used to quote special characters in an expression so their literal value can be used. The character following the backslash in this expression has no affect on the character. Consider simplifying the expression. | ||
| coreTcl::warnQuoteChar | Upgrade Warning | "\" in bracket expressions are treated as quotes |
| The new regular expression package introduced in Tcl 8.1 changed the semantics of the backslash character inside of bracket expressions. Previously they were treated as literal characters. Now they are treated as a quote character. To maintain the behavior of previous versions of Tcl, add another backslash before the existing backslash (for example, [*-\] becomes [*-\\]). (This warning is displayed only if you specify the -use option with Tcl 8.0 or earlier.) | ||
| coreTcl::warnY2K | Warning | %y generates a year without a century. consider using %Y to avoid Y2K errors |
| To avoid possible Y2K errors, use the "%Y" field descriptor to generate years with centuries (for example, "1999" instead of "99"). | ||
| Message ID | Category | Message String |
| coreTk::badBindSubst | Error | Bind script contains unknown -placeholders |
| This error indicates that a placeholder character specified with the "bind" command is invalid. Refer to the ActiveTcl User Guide for "bind" command specifications. | ||
| coreTk::badColormap | Error | Invalid colormap "colormap": must be "new" or a window name |
| The command expects the string to specify a colormap to use. If the string is "new", a new colormap is created. Otherwise, the string should be a valid window path name. | ||
| coreTk::badEvent | Error | Invalid event type or keysym |
| The command expects the string to specify an event type. If the string is not composed of a valid event and one or more related modifiers, an error is reported. | ||
| coreTk::badGeometry | Error | Invalid geometry specifier |
The command expects the string to specify a geometry value.
The string must have one of the following forms:
...where the width (W) and height (H) values are positive integers, and the X (X) and Y (Y) coordinates are positive or negative integers. |
||
| coreTk::badGridMaster | Error | Cannot determine master window |
| The grid command flags an error if a valid window name was never specified in the command. | ||
| coreTk::badGridRel | Error | Must specify window before shortcut |
| When using the relative placement shortcuts in the grid command (that is, "-", "x", or "^") an error is reported if the span column shortcut ("-") is used immediately after one of the other shortcuts. | ||
| coreTk::badPalette | Error | Invalid palette spec |
| The command expects the string to be a valid palette specification. The palette string may be either a single decimal number, specifying the number of shades of gray to use, or three decimal numbers separated by slashes ("/"), specifying the number of shades of red, green and blue to use, respectively. | ||
| coreTk::badPriority | Error | Invalid priority keyword or value |
| The command expects the string to specify a priority value. The string must contain one of the following values: "widgetDefault", "startupFile", "userDefault", "interactive", or an integer between 0 and 100. | ||
| coreTk::badScreen | Error | Invalid screen value |
The command expects the string to specify a screen value.
The string must have the following form:
?name ?:display ?.screen ? ...where name is any string and display and screen are integers. |
||
| coreTk::badSticky | Error | Invalid stickiness value: should be zero or more of nswe |
| The grid command expects the string to specify valid sticky coordinates. The string can contain any combination of the following characters: "n", "s", "e". or "w". | ||
| coreTk::badTab | Error | Invalid tab list |
| The command expects a list of strings that define tab stops. If the Tcl interpreter cannot parse the list, an error is flagged. The tab list must consist of a list of screen distances giving the positions of the tab stops. Each position can optionally be followed in the next list element by one of the keywords "left", "right", "center", or "numeric", which specifies how to justify text relative to the tab stop. | ||
| coreTk::badTabJust | Error | Invalid tab justification "tab-item": must be left right center or numeric |
| The command expects the justification string to be one of the following: "left", "right", "center", or "numeric". | ||
| coreTk::badVirtual | Error | Virtual event is badly formed |
The command expects the string to specify a virtual
event. The string must have the following form:
<<word>> ...where word is any non-empty string. |
||
| coreTk::badVisual | Error | Invalid visual |
The command expects the string to specify a visual.
The string can have the following form:
The class string must be one of "directcolor", "grayscale", "pseudocolor", "staticcolor", "staticgray", or "truecolor", or any unique abbreviation. The depth value must be a valid integer. |
||
| coreTk::badVisualDepth | Error | Invalid visual depth |
| If the depth specified by a visual string is not a valid integer, then this error is flagged. | ||
| coreTk::noEvent | Error | No events specified in binding |
| coreTk::nonPortBitmap | Non-Portable Warning | Use of non-portable bitmap |
| A bitmap was specified that is not supported on all platforms. | ||
| coreTk::nonPortKeysym | Non-Portable Warning | Use of non-portable keysym |
| A keysym was specified that is not supported on all platforms. | ||
| The command expects an event but could not find one while parsing the command line. | ||
| coreTk::noVirtual | Error | Virtual event not allowed in definition of another virtual event |
| Virtual events are not allowed in event sequences. If a virtual event (any event that begins with "<<" and ends with ">>") is found, then this message is flagged. | ||
| coreTk::warnConsoleCmd | Warning | Usage of internal console command, may change without notice |
| The "console" command is internal; its functionality may change between Tcl versions. | ||
| coreTcl::warnTkCmd | Warning | Usage of internal tk command, may change without notice |
| The "tk" command is internal; its functionality may change between Tcl versions. | ||
| Message ID | Category | Message String |
| expect::warnAmbiguous | Usage Warning | Ambiguous switch, use delimiter to avoid conflicts |
| The word being checked starts with a "-" but does not match any of the known switches. Use delimiter to explicitly declare the end of the switch pattern. | ||
| Message ID | Category | Message String |
| incrTcl::badMemberName | Error | Missing class specifier for body declaration |
| An [incr Tcl] member name was not correctly qualified. When defining the body for a class procedure, class method, or class variable, it is necessary to reference the procedure or variable with the fully qualified name. | ||
| incrTcl::classNumArgs | Error | Wrong # args for class constructor: className |
| The wrong number of arguments are being used to instantiate the [incr Tcl] class className . Compare the number of arguments used to instantiate the class to the number of arguments in the constructor defined by className. | ||
| incrTcl::classOnly | Error | Command "command" only defined in class body |
| The specified command is only valid in the context of an [incr Tcl] class body. | ||
| incrTcl::nsOnly | Error | Command "command" only defined in namespace body |
| The specified command is only valid in the context of an [incr Tcl] namespace body. | ||
| incrTcl::nsOrClassOnly | Error | Command "command" only defined in class or namespace body |
| The specified command is only valid in the context of an [incr Tcl] class or namespace body. | ||
| incrTcl::procOutScope | Error | Proc only defined in class className |
| An [incr Tcl] class procedure is being called from the wrong scope, or is improperly qualified. This commonly occurs when calling inherited procedures. | ||
| incrTcl::procProtected | Error | Calling protectionLevel proc: procName |
| You are calling an inaccessible procedure with a protection level of protectionLevel. This error is flagged when the procedure being called does not have permission to call this procedure. | ||
| incrTcl::warnUnsupported | Error | Command deprecated and is no longer valid |
| The incrTcl command is not supported in the current version of Tcl. | ||
| Message ID | Category | Message String |
| oratcl::badConnectStr | Error | Invalid Oracle connect string |
| Refer to the "oratcl" manpages or the Oracle documentation for information about connect string syntax. | ||
| oratcl::badOnOff | Error | Invalid "on" or "off" value |
| The "oraautocom" command requires a literal "on" or "off" value. Refer to the "oratcl" manpages or the Oracle documentation for more information. | ||
| oratcl::badSubstChar | Error | Invalid Oracle substitution character |
| An invalid substitution character has been passed with the "orafetch" command. Refer to the "oratcl" manpages or the Oracle documentation for more information. | ||
| oratcl::missingColon | Error | varName must be preceded by ':' |
| Variable names must begin with colons. Refer to the "oratcl" manpages or the Oracle documentation for more information. | ||
| Message ID | Category | Message String |
| tclX::badLIndex | Error | Invalid infants: should be integer, "len" or "end" |
| The command expects the string to specify an index value. The string can be an integer, "len", or "end". | ||
| tclX::badProfileOpt | Error | Option "option" not valid when turning off profiling |
| Using the TclX profiling tools, option is not valid. Most likely the option is valid only when turning on profiling. | ||
| tclX::badTlibFile | Error | The filename must have a ".tlib" suffix |
| The command expected a filename with a .tlib suffix. The word should be changed to match the pattern filename.tlib. | ||
| tclX::optionRequired | Error | Expected option1, got "option2" |
| A specific option was expected, but the following option was found. | ||
| Message ID | Category | Message String |
| xmlAct::badXMLaction | Error | Invalid action, must be start children, end, or all |
This section provides a general overview on TclChecker definition files, including how to name and load them for use with the tclchecker tool. Later, this document provides information for building custom TclChecker definition files using the PCX API.
TclChecker definition files are used with the tclchecker tool to analyze Tcl code for errors. TclChecker definition files have a ".pcx" extension. For each Tcl package you wish to analyze using tclchecker, there must be a corresponding ".pcx" file. This file declares the method by which the commands contained in the source Tcl package are checked. TclChecker definition files are written using the PCX API.
Note: This document uses the terms "TclChecker definition file", "PCX file", and "checker package" to identify the file used by the tclchecker tool to check Tcl code.
PCX files also contain definitions extending the rules used by tclchecker to analyze Tcl package sources. Fundamentally, each PCX file contains a Tcl script, which is executed by the tclchecker when the file is loaded.
Warning: Tcl code contained in PCX files is trusted. This means that PCX files are run directly by the Tcl interpreter and are not parsed with the tclchecker tool. When a PCX file is executed it should restrict itself to the PCX API. Because this code is executed without restriction it can potentially redefine everything in the program being checked (including functions, variables etc.).
The Tcl Dev Kit TclChecker comes with embedded PCX files for
standard Tcl packages. Examples include: 'Tk', 'Expect', and 'Blt'. To view an
embedded PCX file, use the Tcl Dev Kit Virtual Filesystem
Explorer tool to navigate to the "pcx" directory
(located, by default, in
<installdir>bin/tclchecker.tcl/data/pcx),
and then save the PCX file to an existing folder.
To use tclchecker on packages without an embedded PCX definition file, you must create a custom PCX file. For more information, see Using the PCX API.
When creating custom PCX files for use with a Tcl package, the name of the
PCX file must match the Tcl package name exactly. For example, if a Tcl package
is loaded using the command package require FoO, then the
PCX file containing the checker definitions for this package must also be named
FoO.pcx (case must match exactly).
Note: For platforms with case-insensitive filesystems (such as Windows), all package names must be unique. For example, filenames like 'expect.pcx' and 'Expect.pcx' should not be used as they are considered the same file.
Tcl searches various paths for PCX files. These paths are determined on startup. The first time a PCX file is required in a package through the package require command, the paths are scanned and a list that maps package names to PCX files is created.
Note: Subdirectories in the search path are not scanned as the checker does not search recursively.
To disable the usage of all PCX files during Tcl Dev Kit TclChecker sessions, specify the option -nopcx. Otherwise, PCX files are loaded on demand as needed. A file is determined to be needed if the code scanned by the checker contains a valid require statement for that package.
To specify additional locations where the Tcl Dev Kit TclChecker should look for PCX files, specify the option -pcx directory. The Tcl Dev Kit TclChecker will look for PCX files in the following locations and order (unless the -nopcx option is specified):
tclchecker.exe.lib directory of the Tcl Dev Kit installation.TCLDEVKIT_LOCAL.Note: If multiple PCX files with the same name occur in more than one location, the last file encountered by the checker is loaded. If the files contain conflicting settings, the setting encountered in the last PCX file is used.
This section outlines how to build a custom PCX file for use with the Tcl Dev Kit TclChecker. The PCX file for 'Tk' is used to demonstrate the format of a standard checker package.
A PCX file contains two types of declarations, these are:
Every PCX file must begin and end with the following two
pcx:: declarations:
pcx::register declaration must be the first
pcx:: command called after loading the
PCX API.
pcx::complete command must be the last command called
in the PCX file.Otherwise, declarations can be placed in any order within a PCX file. For readability purposes, however, it is recommended you separate PCX declarations into the following three sections:
pcx::register command. These are checker commands used in
rule definitions and other arbitrary commands to support them.
These conditional declarations
are defined during loading and are used only after rule definitions are
activated.The PCX file management header contains the declarations that are global to the PCX checker package.
Tk Package Example: The PCX management header from the Tk package.
# ### ######### ########################### ## Requisites package require pcx ; # PCX API package require analyzer ; # Analyzer API (checker commands definitions). # ### ######### ########################### ## Tcl core version dependencies of the package this checker is for. pcx::register coreTk Tk pcx::tcldep 3.6 needs tcl 7.3 pcx::tcldep 4.0 needs tcl 7.4 pcx::tcldep 4.1 needs tcl 7.5 pcx::tcldep 4.2 needs tcl 7.6 pcx::tcldep 8.0 needs tcl 8.0 pcx::tcldep 8.1 needs tcl 8.1 pcx::tcldep 8.2 needs tcl 8.2 pcx::tcldep 8.3 needs tcl 8.3 pcx::tcldep 8.4 needs tcl 8.4 # ### ######### ###########################
Description:
pcx package is loaded to provide access to all
tclchecker APIs.pcx::register command. The analyzer package
loads the APIs used for custom TclChecker commands.
Note: The analyzer package is required in
this example for clarity. Because this package is automatically loaded, it
does not need to be specified in your custom PCX file. pcx::register coreTk Tk statement declares that this
PCX file uses the ::coreTk namespace internally, and that
the Tk package is associated with this file.pcx::tcldep statements then declare
which version pairs of Tcl and Tk are supported by the PCX file.
The first column of numbers (second column from the left) declares which
Tk packages are supported. The last column of numbers (rightmost column)
declares the minimum Tcl version required to support the PCX file.
The text 'needs tcl' is required, and is checked. Note:
If no version pairs are declared then tclchecker
assumes the default version of Tcl.Rule definitions comprise the second part of a PCX checker file. Rule definitions map commands and variables to actions. Rules are defined in PCX files and are associated with a function or variable in a corresponding source package. A rule executes an action when tclchecker encounters the variable or function in the Tcl source specified in the corresponding PCX file. Possible actions include: printing custom warning or error messages, or indicating incorrect usage of a variable or function. The latter example requires use of the analyzer API to write custom checker commands.
There are two interfaces available for defining rules, simple and advanced. The simple interface uses the pcx::init function to initialize rule definitions. The advanced interface provides greater flexibility for rule definition as all initialization must be done through a custom init procedure. Both have comparable APIs; the simple interface serves as a wrapper for the advanced interface.
There are four types of rules in both the simple and advanced interfaces. These are:
The simple rule interface uses the pcx::init procedure to automatically load rules and package versions. The pcx::init function performs the calls into the advanced interface. The simple interface commands for defining the four types of rules are: pcx::scan, pcx::check, pcx::var, and pcx::mathop. See Initializing Rules for more information on the pcx::init command.
The pcx::scan command defines tclchecker scanning rules. Command syntax follows:
pcx::scan [ver] [cmd] <def>
[ver] is the package version the rule defines.[cmd] is the name of the command to be checked.<def> is the rule definition. This parameter is optional,
if not specified then the analysis command is used during scanning.The pcx::check command defines tclchecker analysis rules. Command syntax follows:
pcx::check [ver] [mode] [cmd] [def]
[ver] is the package version the rule defines.[mode] is always std.[cmd] is the name of the command to be checked.[def] is the rule definition.The pcx::var command defines variable (var) rules. Command syntax follows:
pcx::var [ver] [varname]
[ver] is the package version the rule defines.[varname] is the fully qualified name of the
variable. The full namespace must be included.The pcx::mathop command defines operator/math rules. Command syntax follows:
pcx::mathop [ver] [opname] [oparity]
[ver] is the package version the rule defines.[opname] is the name of the math function or operator.[oparity] is the number of arguments expected by the math function or operator.Versioning with the simple interface is a less intensive method of defining the relationship between rules and package versions. This is because the pcx::init function scans for version number information and initializes the correct version of the rule with the corresponding package version. If pcx::init does not find a rule matching the provided package version, pcx::init then initializes the rule with the largest version number below the specified version. For example, if a PCX file contains rule definitions for package versions 8.0, 8.1, 8.2, 8.4 and the package being loaded has version 8.3, then the rule for version 8.2 is loaded.
Limitation: It is impossible to rename or delete commands and variables from a PCX file in future package versions using the simple interface. This is because once a rule is defined for a command and a package version, all future packages will load a rule for that command. For example, if package version 8.2 contains the command Foo with a matching 8.2 version rule defined in the PCX file, and this command is removed in version 8.3, then using that PCX file will still load rule 8.2 for the Foo command. To handle this limitation of the simple interface, the PCX developer must use the advanced interface described in the following section.
The advanced rule interface uses a custom init procedure to define rules and package versions. The advanced interface commands pcx::checkers, pcx::scanners, pcx::variables, and pcx::mathoperators must be placed within the body of the init function to be correctly defined. Beyond this requirement, there are no restrictions on how definitions are stored. Lastly, defining rules with the advanced interface handles the limitation of the simple interface where commands could not be renamed between package versions. This is accomplished through using the version passed to the init function to ensure that the correct rule is activated. See Initializing Rules for more information on custom init commands.
See Appendix A: PCX API Commands for the full advanced interface definition.
This section demonstrates, through the 'Tk' package, how to define custom messages and initialize rules.
Defining Custom Messages
Tk Package Example: Defining new messages.
# ### ######### ###########################
## Package specific message types and their human-readable translations.
pcx::message badColormap {invalid colormap "%1$s": must be "new" or a window name} err
# ### ######### ###########################
Description:
pcx::message command defines new message codes
for the errors and warnings generated by the PCX file. The syntax is as
follows:pcx::message [code] [text] [types]
[code] parameter is the ID of the new message.pcx::message command
the messageID must be specified without a namespace prefix.
This is because pcx::message automatically adds the name of
the checker package as a prefix to the messageID. However, when the
message ID is used to display a message with the logError
command the prefix has to be specified. For example,
coreTk::badColorMap[text] parameter is the human readable
string displayed by tclchecker.
This string may contain placeholders of the form '%<digit>$s'.
When the message is displayed, these placeholders will be replaced with
the additional arguments given to the 'logError' call. The <digit>
placeholder specifies which argument to use starting from '1'.[types] parameter is a list of message types used by
message filtering mechanism in tclchecker.
Legal type codes are 'err', 'warn', or 'upgrade'.Tk Package Example: Initializing rules in the PCX file.
# ### ######### ###########################
proc ::coreTk::init {ver} {
::pcx::init coreTk $ver
}
# ### ######### ###########################
Description:
::coreTk is used to declare all messages
and rules. Rule definitions and messages must be declared
in the namespace reserved for the PCX checker definition. Namespaces are
defined in the management header.init command activates the rule definitions for the
specified version of the source package. If the PCX file
does not declare a custom init command,
tclchecker will define the command as shown
above. Important: The pcx::init command
should always be called from the init function to ensure
that simple rule definitions are loaded.| Simple API: | Advanced API: | Rule Type: | Definition: | Notes: |
| pcx::scan | pcx::scanners | Scanning | Scan command rules. | Always taken. |
| pcx::check | pcx::checkers | Analysis in std mode. | Analysis command rules. | Always taken. |
| pcx::var | pcx::variables | Variable | Variables declared by the package. | Always taken. |
| pcx::mathop | pcx::mathoperators | Variable | Math functions declared by the package. | Always taken. |
The final section of a PCX checker package contains supporting code. Supporting code consists of a series of procedure and variable definitions for more complicated rule definitions. All supporting code must be defined in the namespace reserved for the PCX checker package. A procedure can be a custom checker command, or a regular command supporting checker commands. Checker commands must follow additional restrictions for correct interoperation with tclchecker.
See Using the Analyzer API for information on checker command syntax.
For information on available checker commands, see Appendix B: Analyzer API Commands.
The Analyzer API is used to write custom checker commands. A checker command is a fundamental building block for checking a Tcl source file command. Checker commands ensure that arguments passed to a function in the Tcl source file are correct. Whenever tclchecker files check the invocation of a command, they consult an internal database that maps command names to checker commands. The tclchecker tool retrieves the checker command associated with the command that occurs in the source package and evaluates it according to the configuration in the checker package (PCX file). The database does not directly map to a command, but rather to the command prefix. This means it is possible to use a single generic checker command for many commands, with suitable parameterization.
Checker commands take at least two arguments. The first arguments are user-defined. The second-last argument is a list containing the arguments passed to the function being checked. The last argument is the index of the current argument being checked. The interface for a checker command is as follows:
proc checkFoo {... token index} {body}
Description:
checkFoo is a
checker command for a 'Foo' function.token parameter is the list of arguments from the
function being checked. This list describes the command and its
components in detail, as generated by the parser package.index parameter indicates which item in the
token list is currently being checked.body is the checker command code. Generally, checker
command code will contain calls into the analyzer interface to process the
argument list.For information on available checker commands, see Appendix B: Analyzer API Commands.
The checker command interface can be used to write generic checker commands, as well as checker commands which call other checker commands to perform the actual task. The latter usage requires the chaining or grouping of checker commands.
Chaining: A primary checker command performs some tasks, and then passes the remaining tasks to a subsequent checker command. The subsequent command is explicitly specified as an argument to the primary checker command. Other subsequent checker commands may follow.
Grouping: A primary checker command has several other checker commands as arguments. The primary command then calls the subsequent commands in various patterns.
Reserves <namespace> for PCX definitions of package <pkg>. Defines <namespace> as the name of the new checker package. If <pkg> is missing, <namespace> replaces it.
Declares the <namespace> for the checker package. Use <version> to list supported source packages. Use ?<tclver>? to map source package versions to required Tcl versions.
Ensures presence of a PCX file for the package in memory. Use when a PCX file uses a definition of another file. For example, Blt asks for Tk.
Advanced API. Accepts a serialized array that maps command names to scanner definitions.
Advanced API. Activates the checker definitions for the listed commands. Accepts a serialized array that maps command names to checker definitions.
Advanced API. Activates variable definitions in the checker. Takes a list of variables to define.
Advanced API. Activates operator/math definitions in the checker. Takes a list of math functions to define, each in the form <opname>/<oparity>.
Returns the current scanner/checker definition for the command. Empty if there is no definition for the command. Used by checker packages to conditionally define commands, and to copy an existing definition for use in a new one.
Common setup command for definitions. Uses checkers, scanners, and variables to activate definitions stored <namespace> variables in. Activates the definitions of version <ver>.
Simple API. Defines tclchecker scanning rules.
Simple API. Defines tclchecker analysis rules.
Simple API. Defines variable rules.
Simple API. Defines operator/math rules.
Tests if the checker package in <namespace> has active definitions. Returns a boolean: 'true' if active, 'false' otherwise. The active version is stored in the second argument, a variable name.
Returns the version of the checked package <pkg>, or '-1' if the package is not checked. Used in new checker commands to place conditions on checks.
Use the Analyzer API to build custom checker commands.
Pushes a context on the context stack, then calls the chained checker.
cIndex: Index of the word containing the context information.
strip: Boolean, set if word containing context name has to have the head stripped off.
For scan commands.
Checks a "proc" for the correct number of arguments.
pInfo: Proc declaration (argument lists)
Checks if the procedure in the word to check is defined more than once.
Check a script in a single word (procedure body, control commands).
Check if the word contains subcommands, etc. and invokes their checker commands.
Check the expression for subcommands, etc.
Checks each word (checkWord) in the command.
Checks that the number of arguments is between min and max. If that is not the case we default to checkCommand to check all words. If the number of words is in the specified range we go through the list of checkers and execute them. Each checker is started where its predecessor left off. If there are words left to check after the last checker was executed the execution of the last checker is repeated until there are no words left.
A value of -1 for max means that the number of arguments has no finite upper bound.
This is the basic sequential composition operator.
Similar to the previous checker, but not quite. "backup" is the number of fixed tail arguments for the command. These are checked through the execution of tailCmd. All other arguments are checked with headCmd. The head arguments are checked before the tail arguments.
If the head checker did not process an argument, checkWord will be used instead. This happens until all head arguments are processed.
See checkTailArgs, but the tail arguments are checked before the head arguments.
This command checks switch arguments similar to the checkSimpleArgs checker. It checks to see if the minimum number of words can be found in the current command, and then checks "num" args. This checker is designed to be used inside custom checkers to assist checking switch arguments (e.g., the "expect" command.)
This is the primary composition operator for handling of subcommands (here called "options").
The optionTable is a list of 2-tuples mapping from subcommand names to checkers for the arguments after the subcommand.
If none of the options match, the 'default' checker is used. If the default is empty an error will be generated for that case.
Defaults to checkCommand if the subcommand word is not literal.
Convenience wrapper to checkConfigure, see below.
Checks that the next word is on the list of allowed keywords. If exact is not set, unique abbreviations of the keywords are allowed too. Falls back to checkWord for non-literals.
Similar to checkKeyword. Differences:
If a switch with an action is found the checker in the action is executed for the switch argument.
Similar to checkSwitches. Does not check for switches beyond the 'backup' tail arguments of the command. Ignores arguments behind the switches.
Similar to checkSwitches. Does not check for switches beyond the 'backup' tail arguments of the command. Ignores arguments behind the switches.
Similar to checkSwitches. Difference: Decouples the execution of checkers for a switch from the notion that a switch takes an argument. This allows for switches without arguments, yet needing a checker, for example to warn about portability problems with said switch.
Options is a list of switch/action pairs. If allowsingle is set, a single argument is ok. Otherwise an error is generated. Checks the arguments for options and values as defined in the table.
See checkConfigure above, but does not check the option values.
A list of 2-tuples. First element of a tuple is the number of arguments triggering the checker specified as the second element of that tuple.
Basic behavior as checkSimpleArgs, but for checking a list, not a command.
Checks that next word is a valid level designator (#n, n) and then invokes the chained checker.
Number of non-literal arguments to append to the proc call. Ignored.
See checkBody, but script is distributed over a list of arguments (examples: eval, after, ...).
See checkSwitches for basic behavior. Difference: Stops at first unrecognized switch, and does not log unrecognized switches as error.
These commands check the validity of variable names.
Checking that the next words is of a specific type:
Generates an error/warn message and then invokes the chained checker.
Type of token.
A list of tokens.
Length of the token list.
String in the script for the token.
Tests if the word is literal and without any substitutions.
If a literal word, the exact literal value of the token. The value is stored in the named variable.
Returns offset in the script for the position in the word.
Extended to a range, where range = {start size}