<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Nagelfar - A Tcl Syntax Checker</title>
<meta http-equiv="content-type"
content="text/html; charset=ISO-8859-1">
</head>
<body>
<a href="http://sourceforge.net">
<img style="float:right; padding-right:10px;padding-top:2px;"
src="http://sourceforge.net/sflogo.php?group_id=695858&type=13"
alt="SourceForge.net" /></a>
Bug tracker and mailing list can be found at the
<b><a href="https://sourceforge.net/projects/nagelfar/">Project page</a></b>
<h1>Nagelfar - A Tcl Syntax checker</h1>
<a href="#NagelfarDownload">Download</a>
<a href="#NagelfarFeatures">Features</a>
<a href="#NagelfarChanges">Changes</a>
<a href="doc.html">Documentation</a>
<a href="check.html">Demo</a>
<p>
<h3>About Nagelfar</h3>
In 1999 I got an idea about how I wanted a syntax checker to work,
and that led to a couple of evenings of massive hacking. After that
it mainly collected dust for a few years before it caught my interest
again. This had a lot to do with a synthesis script crashing due to
a misspelled variable after running for 30 hours.<br>
After some regular usage by me it is getting stable and can catch a lot
of common errors.
<p>
Nagelfar sometimes uses coding style to help checking code. Some constructs
that are perfectly legal Tcl gives warnings just because they deviate
from what is "normal". For example, it checks brace indentation,
braced expressions and enforces the <i>else</i> keyword.<br>
Naturally Nagelfar expects the coding style of its author so if you
do things differently, you may get false errors. I am very interested
in hearing about such things to be able to make Nagelfar more general.
<p>
Any feedback, good or bad, can be sent to
<peter <i>dot</i> spjuth <i>at</i> gmail <i>dot</i> com>
<p>
<a href="http://wiki.tcl.tk/3162">See also this page for other syntax checkers.</a>
<p>
<h4>The name</h4>
Pronunciation: Both a:s are pronounced like in "far". The g is hard. Stress
on the first syllable. That should get you close enough :-).
<p>
Nagelfar is the name of a ship in Nordic mythology. It is made out of dead
people's untrimmed nails (nail == nagel) and when finished the bad guys will
set it to sea and destroy the world. So if you die with untrimmed nails,
you bring the world closer to its end. What that has to do with syntax
checking is hard to say, but keeping nails and code in shape could be
a connection. There is also a Swedish word "nagelfara" which means
"examine thoroughly" but that has nothing to do with this tool.
<p>
<a name="NagelfarFeatures"></a><h3>Features</h3>
<ul>
<li>Written in pure Tcl/Tk. No compilation. If you can run Tcl you can run
Nagelfar.</li>
<li>Extendible. You can add to the syntax database, or let the tool use
Tcl's introspection to extract syntax information from any Tcl
interpreter. Thus you can test scripts for applications using Tcl as
script language.</li>
<li>Plugins. Even more extendible through plugins that can hook up at certain
points in the check flow and do custom checking.</li>
<li>Severity level filter and glob matching filters to remove errors
known to be ok.</li>
<li>View and edit the checked source directly in Nagelfar.</li>
<li>Inline comments can help Nagelfar do a better job.</li>
<li>Code coverage instrumentation. Provides help for simple code coverage
analysis.</li>
</ul>
To get a feeling of what it can do, here is a test script that is part of
the distribution with errors it can detect, and the output from the tool.
<p>
<table cellpadding="2" cellspacing="0" border="1">
<tbody>
<tr>
<th>Test File</th>
<th>The result of checking it:</th>
</tr>
<tr>
<td style="vertical-align: top; white-space: nowrap;"><pre>
<span style="color: #808080"> 1</span> proc apa {} {
<span style="color: #808080"> 2</span>
<span style="color: #808080"> 3</span> set bepa 1
<span style="color: #808080"> 4</span> <span style="color: #b22222"># Detect missing $</span>
<span style="color: #808080"> 5</span> set cepa bepa
<span style="color: #808080"> 6</span> <span style="color: #b22222"># Detect unknown or misspelled variable</span>
<span style="color: #808080"> 7</span> set depa $cep
<span style="color: #808080"> 8</span> set epa
<span style="color: #808080"> 9</span> <span style="color: #b22222"># Detect bad $</span>
<span style="color: #808080"> 10</span> set $depa apa
<span style="color: #808080"> 11</span> if {[info exists $cepa]} {
<span style="color: #808080"> 12</span> <span style="color: #b22222"># Detect wrong number of args</span>
<span style="color: #808080"> 13</span> set apa bepa cepa
<span style="color: #808080"> 14</span> }
<span style="color: #808080"> 15</span> <span style="color: #b22222"># Detect ugly if</span>
<span style="color: #808080"> 16</span> if {$bepa == $cepa} {
<span style="color: #808080"> 17</span> set hej 1
<span style="color: #808080"> 18</span> } elsif {$bepa == $cepa} {
<span style="color: #808080"> 19</span> set hej 2
<span style="color: #808080"> 20</span> } else {
<span style="color: #808080"> 21</span> set hej 3
<span style="color: #808080"> 22</span> }
<span style="color: #808080"> 23</span> <span style="color: #b22222"># Detect bad subcommand</span>
<span style="color: #808080"> 24</span> info gurka
<span style="color: #808080"> 25</span>
<span style="color: #808080"> 26</span> <span style="color: #b22222"># Detect bad switch comment</span>
<span style="color: #808080"> 27</span> switch $bepa {
<span style="color: #808080"> 28</span> hej {
<span style="color: #808080"> 29</span> set hej hopp
<span style="color: #808080"> 30</span> }
<span style="color: #808080"> 31</span> <span style="color: #b22222"># This is bad</span>
<span style="color: #808080"> 32</span> hopp {
<span style="color: #808080"> 33</span> <span style="color: #b22222"># Detect a missing command</span>
<span style="color: #808080"> 34</span> miffo
<span style="color: #808080"> 35</span> }
<span style="color: #808080"> 36</span> }
<span style="color: #808080"> 37</span> }
<span style="color: #808080"> 38</span>
<span style="color: #808080"> 39</span> <span style="color: #b22222"># Test call-by-name handling</span>
<span style="color: #808080"> 40</span> <span style="color: #b22222"># The syntax of this proc is described in</span>
<span style="color: #808080"> 41</span> <span style="color: #b22222"># the file test.syntax</span>
<span style="color: #808080"> 42</span> proc copy {srcName dstName} {
<span style="color: #808080"> 43</span> upvar $srcName src $dstName dst
<span style="color: #808080"> 44</span> set dst $src
<span style="color: #808080"> 45</span> }
<span style="color: #808080"> 46</span>
<span style="color: #808080"> 47</span> proc testCopy {} {
<span style="color: #808080"> 48</span> set apa 1
<span style="color: #808080"> 49</span> <span style="color: #b22222"># It should not warn about apa below</span>
<span style="color: #808080"> 50</span> copy apa bepa
<span style="color: #808080"> 51</span> <span style="color: #b22222"># Bepa should be known now</span>
<span style="color: #808080"> 52</span> set cepa $bepa
<span style="color: #808080"> 53</span>
<span style="color: #808080"> 54</span> <span style="color: #b22222"># Detect $ mistake</span>
<span style="color: #808080"> 55</span> copy apa $bepa
<span style="color: #808080"> 56</span> copy $apa bepa
<span style="color: #808080"> 57</span> }
<span style="color: #808080"> 58</span>
<span style="color: #808080"> 59</span> proc bepa {} {
<span style="color: #808080"> 60</span> <span style="color: #b22222"># Missing quote</span>
<span style="color: #808080"> 61</span> set apa "hej hopp
<span style="color: #808080"> 62</span> }
<span style="color: #808080"> 63</span> <span style="color: #b22222"># A quote just to fix syntax coloring "</span>
<span style="color: #808080"> 64</span>
<span style="color: #808080"> 65</span> proc cepa {} {
<span style="color: #808080"> 66</span> <span style="color: #b22222"># Missing bracket</span>
<span style="color: #808080"> 67</span> set apa [hej hopp
<span style="color: #808080"> 68</span> }
<span style="color: #808080"> 69</span>
<span style="color: #808080"> 70</span> proc epa {} {
<span style="color: #808080"> 71</span> <span style="color: #b22222"># Extra close brace</span>
<span style="color: #808080"> 72</span> if {[string length apa}} {
<span style="color: #808080"> 73</span> set bepa 1
<span style="color: #808080"> 74</span> }
<span style="color: #808080"> 75</span> }
<span style="color: #808080"> 76</span>
<span style="color: #808080"> 77</span> proc fepa {} {
<span style="color: #808080"> 78</span> <span style="color: #b22222"># Commented brace {</span>
<span style="color: #808080"> 79</span> if {[string length apa]} {
<span style="color: #808080"> 80</span> set bepa 1
<span style="color: #808080"> 81</span> }
<span style="color: #808080"> 82</span> }
<span style="color: #808080"> 83</span> }
<span style="color: #808080"> 84</span>
<span style="color: #808080"> 85</span> <span style="color: #b22222"># This should be last in the file, since</span>
<span style="color: #808080"> 86</span> <span style="color: #b22222"># the missing close brace disturbs anything</span>
<span style="color: #808080"> 87</span> <span style="color: #b22222"># after it</span>
<span style="color: #808080"> 88</span> proc depa {} {
<span style="color: #808080"> 89</span> <span style="color: #b22222"># Missing close brace</span>
<span style="color: #808080"> 90</span> if {[string length apa] {
<span style="color: #808080"> 91</span> set bepa 1
<span style="color: #808080"> 92</span> }
<span style="color: #808080"> 93</span> }
</pre></td>
<td style="vertical-align: top; white-space: nowrap;"><pre>
Parsing file test.syntax
Checking file test.tcl
Line 5: W Found constant "bepa" which is also a variable.
Line 7: E Unknown variable "cep"
Line 8: E Unknown variable "epa"
Line 10: N Suspicious variable name "$depa"
Line 11: N Suspicious variable name "$cepa"
Line 13: E Wrong number of arguments (3) to "set"
Line 13: W Found constant "bepa" which is also a variable.
Line 13: W Found constant "cepa" which is also a variable.
Line 18: E Badly formed if statement
Found argument 'elsif' where else/elseif was expected.
Line 24: E Unknown subcommand "gurka" to "info"
Line 31: W Switch pattern starting with #. This could be a bad comment.
Line 31: W Unknown command "This"
Line 31: W Unknown command "bad"
Line 34: W Unknown command "miffo"
Line 55: N Suspicious variable name "$bepa"
Line 56: N Suspicious variable name "$apa"
Line 61: E Could not complete statement.
One double quote would complete the first line
One double quote would complete the script body at line 62.
Line 67: E Could not complete statement.
One close bracket would complete the first line
One close bracket would complete the script body at line 68.
Line 70: E Wrong number of arguments (4) to "proc"
Argument 4 at line 72
Line 72: E Wrong number of arguments (1) to "if"
Line 74: N Close brace not aligned with line 70 (0 4)
Line 75: E Unbalanced close brace found
Line 82: E Unbalanced close brace found
Unbalanced brace in comment in line 78.
Line 88: E Could not complete statement.
One close brace would complete the first line
One close brace would complete at end of line 93.
One close brace would complete the script body at line 94.
Assuming completeness for further processing.
Line 90: E Wrong number of arguments (1) to "if"
Line 93: N Close brace not aligned with line 90 (4 0)
</pre></td>
</tr>
</tbody>
</table>
<a name="NagelfarDownload"></a><h3>Download</h3>
Version 1.2.1:<br>
Is available from the
<a href="https://sourceforge.net/projects/nagelfar/">Project page</a>
, including as a Starkit and as Starpacks for Windows, Linux and Solaris.
<p>
The licence is GPL.
<p>
More information about <a href="http://wiki.tcl.tk/starkit">Starkits</a>
and <a href="http://wiki.tcl.tk/starpack">Starpacks</a>.
<a name="NagelfarChanges"></a><h3>Changes</h3>
Changes in v1.2.1 (2015-02-07):<br>
<ul>
<li> Extended plugins with hooks for variable read and write.</li>
<li> Extended plugins with variable info to all hooks.</li>
<li> Added sqlite3 to package database.</li>
</ul>
Changes in v1.2 (2013-01-04):<br>
<ul>
<li> Added handling of databases for packages. Databases for a few packages like Snit are included.</li>
<li> Autoload package definition on package require. </li>
<li> New plugin system to allow lots of possibilities.</li>
<li> Handle "dict for" better.</li>
<li> Handle "try" better.</li>
<li> Handle "tcl::mathfunc" better.</li>
<li> Fixed bug where filter pragmas could leak to similar line numbers. [Bug 18486] </li>
<li> Added note for unescaped close braces.</li>
<li> Changed inline comment implicitvar to implicitvarns.</il>
</ul>
Changes in v1.1.12 (2011-11-27):<br>
<ul>
<li> Added checks for array/scalar mixup.</li>
<li> More 8.6 support, more of tcloo handled.</li>
<li> Command line -s search builtin database too.</li>
<li> Command line -H added to preceed messages with file name.</li>
<li> Recognise namespace idiom ${ns}::var as non-suspicious.</il>
</ul>
Changes in v1.1.11 (2010-09-30):<br>
<ul>
<li> Do not turn off variable tracking during code coverage instrumentation.
This was needed to be able to cover OO code. Option -novar only suppresses
messages now.</li>
<li> More 8.6 support, e.g. tailcall and more support for OO checking. Still not convenient to check OO though.</li>
<li> New syntax tokens for command and object definitions, needed to pave the way for OO.</li>
<li> New inline command "alias" to link from command to command.</li>
</ul>
Changes in v1.1.10 (2010-05-17):<br>
<ul>
<li> Include 8.6 database. Much support to make OO checking possible. Not convenient yet though.</li>
<li> More 8.5 commands in database. Including msgcat.</li>
<li> Added html output option.</li>
<li> Added support for partial command tokens, for better checking of callbacks.</li>
<li> Added note when encountering newline in command subst.</li>
<li> Added note when encountering expr in an expression.</li>
<li> New inline command "subcmd+" to handle manually added subcommands, e.g. through namespace ensemble.</li>
<li> New inline command "copy" to copy syntax from command to command.</li>
<li> Misc GUI fixes and bug fixes [Bugs 15644, 15645].</li>
<li> Thanks to Hans Goetz for contributions.</li>
</ul>
Changes in v1.1.9 (2008-09-05):<br>
<ul>
<li> Default database is 8.5 based.</li>
<li> More 8.5 commands in database, including ttk.</li>
<li> Detect Ctrl-Z in scripts, notifying about it.</li>
<li> Use the selected encoding on instrumented file and markup file.</li>
<li> Support initial "+" in bind scripts. [FR 3893]</li>
<li> New ##nagelfar nocover pragma.</li>
</ul>
Changes in v1.1.8 (2007-12-05):<br>
<ul>
<li> Added a reset filter option in GUI. [FR 3586]</li>
<li> Added break button in GUI. [FR 3412]</li>
<li> Removed old {expand} syntax.</li>
<li> Added Del button for Db files. [Bug 11109]</li>
<li> Added percentage in coverage output. [FR 3428]</li>
<li> Improved error messages for comments in db files. [Bug 11109]</li>
<li> Check if file is being reinstrumented. [FR 3424]</li>
<li> Made code coverage count number of runs instead of just run/notrun. [FR 3415]</li>
<li> Fixed a bug in expression checking. [Bug 11091]</li>
<li> Check bind scripts in global context. New token "C".</li>
<li> Fixed edit window startup problem.</li>
<li> Filter multiple line messages better in GUI. [Bug 10515]</li>
<li> Corrected syntax for time command. [Bug 10496]</li>
</ul>
Changes in v1.1.7 (2007-02-23):<br>
<ul>
<li> Added sanity check for proc arguments. [FR 3167]</li>
<li> Read .nagelfarrc from current dir first.</li>
<li> Added -exitcode. [Sup 102383]</li>
<li> Added extensions preference. [FR 3102]</li>
<li> Detect inline style comments in db file. [FR 2541][FR 2938]</li>
<li> Check for extra quote at end of word. [Bug 9644]</li>
<li> Detect extra bracketed commands. [FR 2943]</li>
<li> Check for duplicate files in GUI. [Bug 9709]</li>
<li> More filter options on GUI. [Bug 9774][Bug 9826]</li>
<li> Corrected syntax database for regsub. [Bug 9791]</li>
<li> More fconfigure opts in syntax db. [Bug 9607]</li>
<li> Added more missing 8.5 features to syntax db. [Bug 10430]</li>
<li> Thanks to David Cargo for suggestions.</li>
</ul>
<br>
Changes in v1.1.6 (2006-12-03):<br>
<ul>
<li> Remember directories between adding files. [Frq 2921]</li>
<li> Allow to move files in file list with shift-up/down. [Frq 2921]</li>
<li> Include 8.5 syntax database in distribution.</li>
<li> Fixed bug remembering global variables. [Bug 9578]</li>
<li> Support {*} syntax.</li>
<li> Fixed bug in switch check. [Bug 9147]</li>
<li> Include Tk's auto_loaded commands in syntax db.</li>
</ul>
<br>
Changes in v1.1.5 (2006-10-15):<br>
<ul>
<li> Added proc argument name sanity checks.</li>
<li> Fixed header generation bug. [Bug 8500]</li>
<li> Fixed upvar bug. [Bug 8534]</li>
<li> Fixed namespace resolution bug. [Bug 8538]</li>
<li> Check namespace eval better. [Bug 8539]</li>
<li> Fixed bad close brace alignment warning. [Bug 8537]</li>
<li> Recognise FRINK style inline comments. [FR 2540]</li>
<li> Allow level in inline filter comments.</li>
</ul>
<br>
Changes in v1.1.4 (2006-07-05):<br>
<ul>
<li> Improved 8.5 support, allowing source -encoding in instrumenting
and added more new commands to the syntax database.</li>
<li> Allow nagelfar to be loaded embedded.</li>
</ul>
<br>
Changes in v1.1.3 (2006-06-02):<br>
<ul>
<li> Instrument a missing "else" in code coverage, to get branch
coverage.</li>
<li> On Windows, when run in wish there is no stdout so always start
in gui mode.</li>
<li> Made it possible to remove files from database list.</li>
<li> Support vim as editor.</li>
<li> Support different tab settings.</li>
<li> Goto next error, and text search in result window.</li>
<li> Put less important info in gray.</li>
<li> Thanks to Arjen Markus and Andreas Leitgeb for suggestions.</li>
</ul>
<br>
Changes in v1.1.2 (2005-01-31):<br>
<ul>
<li> Added -header flag to generate a syntax file for one or more
tcl files.</li>
<li> Added the option to use emacs to view files instead of the
internal editor.</li>
<li> Added -quiet flag to suppress some output.</li>
<li> Added -glob flag.</li>
<li> Thanks to Yiftach Tzori and Phil Wise for contributions.</li>
</ul>
<br>
Changes in v1.1.1 (2005-01-02):<br>
<ul>
<li> Fixed a bug that prevented instrumenting multiple files.</li>
<li> Preserve header and permissions in instrumented file to allow
an executable file to remain executable after instrumentation.</li>
</ul>
<br>
Changes in v1.1 (2004-12-22):<br>
<ul>
<li> Added support for code coverage instrumentation.</li>
<li> Added -strictappend option to enforce setting a var before
(l)appending to it.</li>
<li> Bugfixes in variable and upvar handling.
<li> Added option to backup file when saving from Edit Window.</li>
<li> Thanks to Uwe Koloska for suggestions and fixes.</li>
</ul>
<br>
Changes in v1.0.2 (2004-09-02):<br>
<ul>
<li> Added database browser for easier access to examples.</li>
<li> Fixed some bugs in resolving namespace proc names.</li>
<li> Always use 2-pass analysis.</li>
<li> Track interp alias "commands".</li>
</ul>
<br>
Changes in v1.0.1 (2004-06-13):<br>
<ul>
<li> Fixed some bugs in {expand} handling. It is still rather incomplete,
examples of live code that needs better handling are welcome. Note
that to check {expand} Nagelfar must be run in an 8.5 interpreter,
and the syntax database must be generated from 8.5 (the distributed
syntax database is currently from 8.4.6).</li>
</ul>
<br>
Changes in v1.0 (2004-05-01):<br>
<ul>
<li> Add multiple files in file add dialog.</li>
<li> Improved option and subcommand checking. Added more info about them
to the syntax database.</li>
<li> Added more ways to use inline comments to help Nagelfar, including
an ignore comment to skip messages for known issues.
</ul>
<br>
Changes in v1.0b3 (2004-03-23):<br>
<ul>
<li> Fixed a bug in option checking where glob chars disturbed things.</li>
<li> Also make sure that option checking is not invoked on args that
cannot be options due to their placement.</li>
</ul>
<br>
Changes in v1.0b2 (2004-02-09):<br>
<ul>
<li> Added -encoding option for scripts that are not in system encoding.</li>
<li> Added registry setting for Windows.</li>
<li> A few minor bugs fixed.</li>
</ul>
<br>
Changes in v1.0b1 (2004-01-29):<br>
<ul>
<li> Recognise if 0 {...} as a comment.</li>
<li> Added a check for bad comments in constant lists.</li>
<li> Added a 2-pass proc checking to improve things when procs are used
before they are defined in a file.</li>
<li> Optimised, improved speed by about 35%.</li>
</ul>
<br>
Changes in v0.9 (2003-12-11):<br>
<ul>
<li> Improved expression checking.</li>
<li> Added upvar detection to handle call-by-name better.</li>
<li> Added a check in the edit window to simplify checking of clips
that are not in files.</li>
</ul>
<br>
Changes in v0.8 (2003-08-14):<br>
<ul>
<li> Bugfixes in options checking and proc checking.</li>
<li> GUI polishing.</li>
</ul>
<br>
Changes in v0.7 (2003-07-23):<br>
<ul>
<li> Tclkit support. Removed FreeWrap support.</li>
<li> Requires Tcl/Tk 8.4.</li>
<li> More knowledge about options in syntax databases.</li>
<li> Some GUI polish including a progress bar and context menu.</li>
<li> Fixed a bug where the script's own procs were not checked properly.</li>
<li> Added a severity level to each message (Note/Warning/Error) and a
severity level filter on output.</li>
</ul>
<br>
Changes in v0.6 (2003-07-08):<br>
<ul>
<li> The application got its name.</li>
<li> Added -filter option to suppress messages.</li>
</ul>
<br>
Changes in v0.5 (2003-02-14):<br>
<ul>
<li> Made it work when wrapped with FreeWrap.
This includes wrapping the syntax database and
supporting <a href="http://sourceforge.net/projects/tkdnd/">TkDnd</a>
if properly placed.</li>
</ul>
<br>
Changes in v0.4 (2002-11-14):<br>
<ul>
<li> Added option to skip variable check.</li>
<li> Added option to enforce 'else' keyword.</li>
<li> Some message improvements and minor bug fixes.</li>
</ul>
<br>
Changes in v0.3 (2002-09-02):<br>
<ul>
<li> Made procedure checking namespace-aware.</li>
<li> Some improvements in syntax database and check engine.</li>
</ul>
<br>
Changes in v0.2 (2002-08-28):<br>
<ul>
<li>Added a GUI, which can be used if you run with wish or in Tcl8.4.<br>
It is still a command line tool but invokes the GUI if no arguments are
given or the option -gui is used.</li>
<li>Changed how syntax databases are located, which simplifies usage a bit.</li>
<li>Sorts output on line numbers to make it easier to follow.</li>
<li>Improved some error messages.</li>
</ul>
</body>
</html>