<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <id>http://jim.berlios.de/</id>
  <title>Jim Tcl News</title>
  <updated>2012-02-09T14:00:00Z</updated>
  <link rel="alternate" href="http://jim.berlios.de/"/>
  <link rel="self" href="http://jim.berlios.de/feed.xml"/>
  <author>
    <name>steveb@workware.net.au</name>
    <uri>mailto:steveb@workware.net.au</uri>
  </author>
  <entry>
    <id>tag:jim.berlios.de,2012-02-10:/articles/no-namespaces-revisited/</id>
    <title type="html">Coping without Namespaces - Revisited</title>
    <published>2012-02-09T14:00:00Z</published>
    <updated>2012-02-09T14:00:00Z</updated>
    <link rel="alternate" href="http://jim.berlios.de/articles/no-namespaces-revisited/"/>
    <content type="html">&lt;p&gt;Back in the article &lt;a href="/articles/no-namespaces/"&gt;Coping without Namespaces&lt;/a&gt;,
we discussed that fact that Jim Tcl did not support namespaces, but
that small changes to the source could be made to allow namespace-based
Tcl code to be ported for use with Jim Tcl.&lt;/p&gt;

&lt;p&gt;Now with &lt;a href="/articles/light-weight-namespaces/"&gt;namespaces supported&lt;/a&gt;
in &lt;a href="/articles/jim-release-0.73/"&gt;Jim Tcl 0.73&lt;/a&gt;, porting Tcl code
which makes use of namespaces is easier than ever.&lt;/p&gt;

&lt;p&gt;Once again, let's consider porting &lt;a href="http://tcllib.cvs.sourceforge.net/viewvc/tcllib/tcllib/modules/dns/dns.tcl"&gt;dns.tcl&lt;/a&gt;
from &lt;a href="http://tcllib.sourceforge.net/"&gt;tcllib&lt;/a&gt; to Jim Tcl.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Firstly an explanation of what was changed.&lt;/p&gt;

&lt;pre class="sh_tcl"&gt;
--- dns.tcl.orig	2012-03-05 13:02:36.000000000 +1000
+++ dns.tcl	2012-03-05 13:02:56.000000000 +1000
@@ -1,3 +1,15 @@
+# dns.tcl - Steve Bennett &amp;lt;steveb@workware.net.au&amp;gt;
+#
+# Modified for Jim Tcl to:
+# - use udp transport by default
+# - use sendto/recvfrom
+# - don't try to determine local nameservers
+# - remove support for dns uris and finding local nameservers
+# - remove logging calls
+#   (both of these in order to remove dependencies on tcllib)
+
+# Based on:
+
 # dns.tcl - Copyright (C) 2002 Pat Thoyts &amp;lt;patthoyts@users.sourceforge.net&amp;gt;
 #
 # Provide a Tcl only Domain Name Service client. See RFC 1034 and RFC 1035
&lt;/pre&gt;

&lt;p&gt;For simplicity, we remove the dependencies on tcllib &lt;code&gt;logger&lt;/code&gt;, &lt;code&gt;uri&lt;/code&gt; and &lt;code&gt;ip&lt;/code&gt; to
allow this example to be self contained. In Jim Tcl the &lt;code&gt;binary&lt;/code&gt; and &lt;code&gt;namespace&lt;/code&gt;
modules are optional, so load them if required.&lt;/p&gt;

&lt;pre class="sh_tcl"&gt;
@@ -31,14 +43,11 @@
 #
 # $Id: dns.tcl,v 1.36 2008/11/22 12:28:54 mic42 Exp $
 
-package require Tcl 8.2;                # tcl minimum version
-package require logger;                 # tcllib 1.3
-package require uri;                    # tcllib 1.1
-package require uri::urn;               # tcllib 1.2
-package require ip;                     # tcllib 1.7
+package require binary
+package require namespace
 
 namespace eval ::dns {
-    variable version 1.3.3
+    variable version 1.3.3-jim2
     variable rcsid {$Id: dns.tcl,v 1.36 2008/11/22 12:28:54 mic42 Exp $}
 
     namespace export configure resolve name address cname \
&lt;/pre&gt;

&lt;p&gt;Since Jim Tcl supports udp out-of-the-box, and it is more efficient,
default to udp rather than tcp. Also comment out the logging calls.&lt;/p&gt;

&lt;pre class="sh_tcl"&gt;
@@ -49,23 +58,13 @@
         array set options {
             port       53
             timeout    30000
-            protocol   tcp
+            protocol   udp
             search     {}
             nameserver {localhost}
             loglevel   warn
         }
-        variable log [logger::init dns]
-        ${log}::setlevel $options(loglevel)
-    }
-
-    # We can use either ceptcl or tcludp for UDP support.
-    if {![catch {package require udp 1.0.4} msg]} { ;# tcludp 1.0.4+
-        # If TclUDP 1.0.4 or better is available, use it.
-        set options(protocol) udp
-    } else {
-        if {![catch {package require ceptcl} msg]} {
-            set options(protocol) udp
-        }
+        #variable log [logger::init dns]
+        #${log}::setlevel $options(loglevel)
     }
 
     variable types
&lt;/pre&gt;

&lt;p&gt;udp is built-in with Jim Tcl.&lt;/p&gt;

&lt;pre class="sh_tcl"&gt;
@@ -248,14 +237,6 @@
         return -code error "no nameserver specified"
     }
 
-    if {$state(-protocol) == "udp"} {
-        if {[llength [package provide ceptcl]] == 0 \
-                &amp;amp;&amp;amp; [llength [package provide udp]] == 0} {
-            return -code error "udp support is not available,\
-                get ceptcl or tcludp"
-        }
-    }
-    
     # Check for reverse lookups
     if {[regexp {^(?:\d{0,3}\.){3}\d{0,3}$} $state(query)]} {
         set addr [lreverse [split $state(query) .]]
&lt;/pre&gt;

&lt;p&gt;udp in Jim Tcl works just like tcp, with &lt;code&gt;readable&lt;/code&gt; event handler being
triggered when the response is available.&lt;/p&gt;

&lt;pre class="sh_tcl"&gt;
@@ -273,6 +254,7 @@
         }
     } else {
         UdpTransmit $token
+        wait $token
     }
     
     return $token
&lt;/pre&gt;

&lt;p&gt;Jim Tcl has no support for async connect, and the parameters to &lt;code&gt;socket&lt;/code&gt; are a little different.&lt;/p&gt;

&lt;pre class="sh_tcl"&gt;
@@ -668,9 +650,9 @@
                                    "operation timed out"]]
     }
 
-    # Sometimes DNS servers drop TCP requests. So it's better to
-    # use asynchronous connect
-    set s [socket -async $state(-nameserver) $state(-port)]
+    # Jim Tcl has no async connect ...
+
+    set s [socket stream $state(-nameserver):$state(-port)]
     fileevent $s writable [list [namespace origin TcpConnected] $token $s]
     set state(sock) $s
     set state(status) connect
&lt;/pre&gt;

&lt;p&gt;Comment out the async connect check.&lt;/p&gt;

&lt;pre class="sh_tcl"&gt;
@@ -683,11 +665,13 @@
     upvar 0 $token state
 
     fileevent $s writable {}
-    if {[catch {fconfigure $s -peername}]} {
-	# TCP connection failed
-        Finish $token "can't connect to server"
-	return
-    }
+
+    # Jim Tcl has no async connect ...
+#    if {[catch {fconfigure $s -peername}]} {
+#	# TCP connection failed
+#        Finish $token "can't connect to server"
+#	return
+#    }
 
     fconfigure $s -blocking 0 -translation binary -buffering none
 
&lt;/pre&gt;

&lt;p&gt;udp in Jim Tcl is easy. Simpy create the socket with &lt;code&gt;socket dgram&lt;/code&gt; and
send with &lt;code&gt;sendto&lt;/code&gt;.&lt;/p&gt;

&lt;pre class="sh_tcl"&gt;
@@ -722,18 +706,10 @@
                                   "operation timed out"]]
     }
     
-    if {[llength [package provide ceptcl]] &amp;gt; 0} {
-        # using ceptcl
-        set state(sock) [cep -type datagram $state(-nameserver) $state(-port)]
-        fconfigure $state(sock) -blocking 0
-    } else {
-        # using tcludp
-        set state(sock) [udp_open]
-        udp_conf $state(sock) $state(-nameserver) $state(-port)
-    }
-    fconfigure $state(sock) -translation binary -buffering none
+    set state(sock) [socket dgram]
+    #fconfigure $state(sock) -translation binary -buffering none
     set state(status) connect
-    puts -nonewline $state(sock) $state(request)
+    $state(sock) sendto $state(request) $state(-nameserver):$state(-port)
     
     fileevent $state(sock) readable [list [namespace current]::UdpEvent $token]
     
&lt;/pre&gt;

&lt;p&gt;Reading from a udp socket is best done with &lt;code&gt;recvfrom&lt;/code&gt;&lt;/p&gt;

&lt;pre class="sh_tcl"&gt;
@@ -879,7 +855,7 @@
     upvar 0 $token state
     set s $state(sock)
 
-    set payload [read $state(sock)]
+    set payload [$state(sock) recvfrom 1500]
     append state(reply) $payload
 
     binary scan $payload S id
&lt;/pre&gt;

&lt;p&gt;Jim Tcl has &lt;code&gt;lreverse&lt;/code&gt; built-in&lt;/p&gt;

&lt;pre class="sh_tcl"&gt;
@@ -1011,17 +987,6 @@
 }
 
 # -------------------------------------------------------------------------
-# Description:
-#   Reverse a list. Code from http://wiki.tcl.tk/tcl/43
-#
-proc ::dns::lreverse {lst} {
-    set res {}
-    set i [llength $lst]
-    while {$i} {lappend res [lindex $lst [incr i -1]]}
-    return $res
-}
-
-# -------------------------------------------------------------------------
 
 proc ::dns::KeyOf {arrayname value {default {}}} {
     upvar $arrayname array
&lt;/pre&gt;

&lt;hr /&gt;

&lt;p&gt;Notice that no namespace-related changes were required when porting this module.&lt;/p&gt;

&lt;p&gt;The latest version of &lt;a href="https://github.com/msteveb/jimtcl/blob/ad3b3c48c9d7e9/examples/dns.tcl"&gt;dns.tcl for Jim Tcl&lt;/a&gt; is
available in git.&lt;/p&gt;

&lt;p&gt;Steve Bennett (&lt;a href="&amp;#109;&amp;#097;&amp;#105;&amp;#108;&amp;#116;&amp;#111;:&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;"&gt;&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;&lt;/a&gt;)&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:jim.berlios.de,2011-12-22:/articles/jim-release-0-73/</id>
    <title type="html">Jim Tcl version 0.73</title>
    <published>2011-12-21T14:00:00Z</published>
    <updated>2011-12-21T14:00:00Z</updated>
    <link rel="alternate" href="http://jim.berlios.de/articles/jim-release-0-73/"/>
    <content type="html">&lt;h2 id="announce-jim-tcl-version-073"&gt;ANNOUNCE: Jim Tcl version 0.73&lt;/h2&gt;

&lt;p&gt;Jim Tcl 0.73 has been released and is available from: &lt;/p&gt;

&lt;p&gt;&lt;a href="http://repo.or.cz/w/jimtcl.git"&gt;http://repo.or.cz/w/jimtcl.git&lt;/a&gt; or &lt;a href="https://github.com/msteveb/jimtcl"&gt;https://github.com/msteveb/jimtcl&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Find out all about Jim Tcl at &lt;a href="http://jim.tcl.tk/"&gt;http://jim.tcl.tk/&lt;/a&gt;&lt;/p&gt;

&lt;h2 id="changes-since-version-072"&gt;CHANGES SINCE VERSION 0.72&lt;/h2&gt;

&lt;p&gt;This release incorporates bug fixes and many new features.
A summary is below. See git for the full changelog.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bugs fixed in version 0.73&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code&gt;exec&lt;/code&gt; on cygwin now correctly passes $::env&lt;/li&gt;
  &lt;li&gt;On mingw and cygwin, &lt;code&gt;--shared&lt;/code&gt; creates libjim.dll rather than libjim.so&lt;/li&gt;
  &lt;li&gt;UTF-8 case folding may change the encoded length&lt;/li&gt;
  &lt;li&gt;Fix a &lt;code&gt;regexp&lt;/code&gt; infinite loop on invalid UTF-8 strings&lt;/li&gt;
  &lt;li&gt;Prevent infinite recursion in &lt;code&gt;eval&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Don&amp;rsquo;t allow &lt;code&gt;upvar&lt;/code&gt; to a higher level&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;regexp&lt;/code&gt; counted matches may be wrong on subsequent use&lt;/li&gt;
  &lt;li&gt;Form feed (\f) is a valid white space character&lt;/li&gt;
  &lt;li&gt;Parsing bug for quoted orphan $&lt;/li&gt;
  &lt;li&gt;Standard handles were not being kept open&lt;/li&gt;
  &lt;li&gt;Fix edge cases with &lt;code&gt;tailcall&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Features added in version 0.73&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Added support for namespaces and the &lt;code&gt;namespace&lt;/code&gt; command&lt;/li&gt;
  &lt;li&gt;The &amp;ldquo;full&amp;rdquo; sqlite3 extension is included in the repo&lt;/li&gt;
  &lt;li&gt;Built-in regexp now support non-capturing parentheses: &lt;code&gt;(?:...)&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Added &lt;code&gt;string replace&lt;/code&gt; and &lt;code&gt;string totitle&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Added &lt;code&gt;info statics&lt;/code&gt; to access proc static variables&lt;/li&gt;
  &lt;li&gt;Added &lt;code&gt;info alias&lt;/code&gt; to access the target of an alias&lt;/li&gt;
  &lt;li&gt;Added &lt;code&gt;build-jim-ext&lt;/code&gt; for easy separate building of loadable modules (extensions)&lt;/li&gt;
  &lt;li&gt;&lt;code&gt;local&lt;/code&gt; now works with any command, not just procs&lt;/li&gt;
  &lt;li&gt;UTF-8 encoding past the basic multilingual plane (BMP) is supported&lt;/li&gt;
  &lt;li&gt;Added &lt;code&gt;tcl::prefix&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Added the &lt;code&gt;history&lt;/code&gt; command to access command line editing and history from scripts&lt;/li&gt;
  &lt;li&gt;Added a Tcl-compatible &lt;code&gt;apply&lt;/code&gt; command&lt;/li&gt;
  &lt;li&gt;Most extensions are now enabled by default&lt;/li&gt;
  &lt;li&gt;Jim Tcl now compiles with MSVC on Windows (but no build support)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Steve Bennett (&lt;a href="&amp;#109;&amp;#097;&amp;#105;&amp;#108;&amp;#116;&amp;#111;:&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;"&gt;&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;&lt;/a&gt;)&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:jim.berlios.de,2011-12-15:/articles/light-weight-namespaces/</id>
    <title type="html">Lightweight Namespaces</title>
    <published>2011-12-14T14:00:00Z</published>
    <updated>2011-12-14T14:00:00Z</updated>
    <link rel="alternate" href="http://jim.berlios.de/articles/light-weight-namespaces/"/>
    <content type="html">&lt;p&gt;New in Jim Tcl v0.73 is (optional) support for namespaces.&lt;/p&gt;

&lt;p&gt;The following is taken directly from README.namespaces in the Jim Tcl repository.&lt;/p&gt;

&lt;hr /&gt;

&lt;h1 id="lightweight-namespaces-for-jim-tcl"&gt;Lightweight Namespaces for Jim Tcl&lt;/h1&gt;

&lt;p&gt;There are two broad requirements for namespace support in Jim Tcl.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;(1) To allow code from multiple sources while reducing the chance of name clashes&lt;/li&gt;
  &lt;li&gt;(2) To simplify porting existing Tcl code which uses namespaces&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This proposal addresses both of these requirements, with the following
additional requirements imposed by Jim Tcl.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;(3) Support for namespaces should be optional, with the space and time overhead
 when namespaces are disabled as close to zero as possible.&lt;/li&gt;
  &lt;li&gt;(4) The implementation should be small and reasonably efficient.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To further expand on requirement (2), the goal is not to be able to run
any Tcl scripts using namespaces with no changes. Rather, scripts
which use namespaces in a straightforward manner, should be easily
ported with changes which are compatible with Tcl.&lt;/p&gt;

&lt;h2 id="implicit-namespaces"&gt;Implicit namespaces&lt;/h2&gt;
&lt;p&gt;Rather than supporting explicit namespaces as Tcl does, Jim Tcl
supports implicit namespaces. Any procedure or variable which
is defined with a name containing ::, is implicitly scoped within
a namespace.&lt;/p&gt;

&lt;p&gt;For example, the following procedure and variable are created
in the namespace &amp;lsquo;test&amp;rsquo;&lt;/p&gt;

&lt;pre class="sh_tcl"&gt;
proc ::test::myproc {} {
  puts "I am in namespace [namespace current]"
}
set ::test::myvar 3
&lt;/pre&gt;

&lt;p&gt;This approach allows much of the existing variable and command
resolution machinery to be used with little change. It also means
that it is possible to simply define a namespace-scoped variable
or procedure without first creating the namespace, and similarly,
namespaces &amp;ldquo;disappear&amp;rdquo; when all variables and procedures defined
with the namespace scope are deleted.&lt;/p&gt;

&lt;h2 id="namespaces-procedures-and-call-frames"&gt;Namespaces, procedures and call frames&lt;/h2&gt;
&lt;p&gt;When namespace support is enabled (at build time), each procedure has an associated
namespace (based on the procedure name). When the procedure is evaluated,
the namespace for the created call frame is set to the namespace associated
with the procedure.&lt;/p&gt;

&lt;p&gt;Command resolution is based on the namespace of the current call frame.
An unscoped command name will first be looked up in the current namespace,
and then in the global namespace.&lt;/p&gt;

&lt;p&gt;This also means that commands which do not create a call frame (such as commands
implemented in C) do not have an associated namespace.&lt;/p&gt;

&lt;p&gt;Similarly to Tcl, namespace eval introduces a temporary, anonymous
call frame with the associated namespace. For example, the following
will return &amp;ldquo;::test,1&amp;rdquo;.&lt;/p&gt;

&lt;pre class="sh_tcl"&gt;
namespace eval test {
	puts [namespace current],[info level]
}
&lt;/pre&gt;

&lt;h2 id="variable-resolution"&gt;Variable resolution&lt;/h2&gt;
&lt;p&gt;The variable command in Jim Tcl has the same syntax as Tcl, but is closer in behaviour to the global command.
The variable command creates a link from a local variable to a namespace variable, possibly initialising it.&lt;/p&gt;

&lt;p&gt;For example, the following procedure uses &amp;lsquo;variable&amp;rsquo; to initialse and access myvar.&lt;/p&gt;

&lt;pre class="sh_tcl"&gt;
proc ::test::myproc {} {
  variable myvar 4
  incr myvar
}
&lt;/pre&gt;

&lt;p&gt;Note that there is no automatic resolution of namespace variables.
For example, the following will &lt;em&gt;not&lt;/em&gt; work.&lt;/p&gt;

&lt;pre class="sh_tcl"&gt;
namespace eval ::test {
  variable myvar 4
}
namespace eval ::test {
  # This will increment a local variable, not ::test::myvar
  incr myvar
}
&lt;/pre&gt;

&lt;p&gt;And similarly, the following will only access local variables&lt;/p&gt;

&lt;pre class="sh_tcl"&gt;
set x 3
namespace eval ::test {
	# This will incremement a local variable, not ::x
	incr x
	# This will also increment a local variable
	incr abc::def
}
&lt;/pre&gt;

&lt;p&gt;In the same way that variable resolution does not &amp;ldquo;fall back&amp;rdquo; to
global variables, it also does not &amp;ldquo;fall back&amp;rdquo; to namespace variables.&lt;/p&gt;

&lt;p&gt;This approach allows name resolution to be simpler and more efficient
since it uses the same variable linking mechanism as upvar/global
and it allows namespaces to be implicit. It also solves the &amp;ldquo;creative
writing&amp;rdquo; problem where a variable may be created in an unintentional
scope.&lt;/p&gt;

&lt;h2 id="the-namespace-command"&gt;The namespace command&lt;/h2&gt;
&lt;p&gt;Currently, the following namespace commands are supported.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;current - returns the current, fully-qualified namespace&lt;/li&gt;
  &lt;li&gt;eval - evaluates a script in a namespace (introduces a call frame)&lt;/li&gt;
  &lt;li&gt;qualifiers, tail, parent - note that these do not check for existence&lt;/li&gt;
  &lt;li&gt;code, inscope - implemented&lt;/li&gt;
  &lt;li&gt;delete - deletes all variables and commands with the namespace prefix&lt;/li&gt;
  &lt;li&gt;which - implemented&lt;/li&gt;
  &lt;li&gt;upvar - implemented&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="namespace-children-exists-path"&gt;namespace children, exists, path&lt;/h2&gt;
&lt;p&gt;With implicit namespaces, the namespace exists and namespace children commands
are expensive to implement and are of limited use. Checking the existence
of a namespace can be better done by checking for the existence of a known procedure
or variable in the namespace.&lt;/p&gt;

&lt;p&gt;Command resolution is always done by first looking in the namespace and then
at the global scope, so namespace path is not required.&lt;/p&gt;

&lt;h2 id="namespace-ensemble"&gt;namespace ensemble&lt;/h2&gt;
&lt;p&gt;The namespace ensemble command is not currently supported. A future version
of Jim Tcl will have a general-purpose ensemble creation and manipulation
mechanism and namespace ensemble will be implemented in terms of that mechanism.&lt;/p&gt;

&lt;h2 id="namespace-import-export-forget-origin"&gt;namespace import, export, forget, origin&lt;/h2&gt;
&lt;p&gt;Since Jim Tcl namespaces are implicit, there is no location to store export patterns.
Therefore the namespace export command is a dummy command which does nothing.
All procedures in a namespace are considered to be exported.&lt;/p&gt;

&lt;p&gt;The namespace import command works by creating aliases to the target namespace
procedures.&lt;/p&gt;

&lt;p&gt;namespace forget is not implemented.&lt;/p&gt;

&lt;p&gt;namespace origin understands aliases created by namespace import
and can return the original command.&lt;/p&gt;

&lt;h2 id="namespace-unknown"&gt;namespace unknown&lt;/h2&gt;
&lt;p&gt;If an undefined command is invoked, the &amp;ldquo;unknown&amp;rdquo; command is invoked.
The same namespace resolution rules apply for the unknown command.
This means that in the following example, test::unknown will be invoked
for the missing command rather than the global ::unknown.&lt;/p&gt;

&lt;pre class="sh_tcl"&gt;
proc unknown {args} {
	puts "global unknown"
}

proc test::unknown {args} {
	puts "test unknown"
}

namespace eval test {
	bogus
}
&lt;/pre&gt;

&lt;p&gt;This approach requires no special support and provides enough flexibility that
the namespace unknown command is not implemented.&lt;/p&gt;

&lt;h2 id="porting-namespace-code-from-tcl-to-jim-tcl"&gt;Porting namespace code from Tcl to Jim Tcl&lt;/h2&gt;
&lt;p&gt;For most code, the following changes will be sufficient to port code.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Canonicalise namespace names. For example, ::ns:: should be written
as ::ns or ns as appropriate, and excess colons should be removed.
For example ::ns:::blah should be written as ::ns::blah
(Note that the only &amp;ldquo;excess colon&amp;rdquo; case supported is ::::abc
in order to support [namespace current]::abc in the global namespace)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The variable command should be used within namespace eval to link
to namespace variables, and access to variables in other namespaces
should be fully qualified&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id="changes-in-the-core-jim-tcl"&gt;Changes in the core Jim Tcl&lt;/h2&gt;
&lt;p&gt;Previously Jim Tcl performed no scoping of command names.  i.e. The
::format command was considered different from the format command.&lt;/p&gt;

&lt;p&gt;Even if namespace support is disabled, the command resolution will
recognised global scoping of commands and treat these as identical.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:jim.berlios.de,2011-11-10:/articles/jim-tcl-tk-2011-paper/</id>
    <title type="html">Jim @ Tcl/Tk 2011</title>
    <published>2011-11-09T14:00:00Z</published>
    <updated>2011-11-09T14:00:00Z</updated>
    <link rel="alternate" href="http://jim.berlios.de/articles/jim-tcl-tk-2011-paper/"/>
    <content type="html">&lt;p&gt;At the &lt;a href="http://www.tcl.tk/community/tcl2011/"&gt;Tck/Tk 2011 conference&lt;/a&gt; I
presented a paper on Jim Tcl. It seemed to be well received.&lt;/p&gt;

&lt;p&gt;You can read the paper by clicking on the image below.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://workware.net.au/papers/jimtcl-tcl-tk-2011.pdf"&gt;&lt;img src="/img/jimtcl-tcl-tk-2011-front.png" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Steve Bennett (&lt;a href="&amp;#109;&amp;#097;&amp;#105;&amp;#108;&amp;#116;&amp;#111;:&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;"&gt;&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;&lt;/a&gt;)&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:jim.berlios.de,2011-10-06:/articles/jim-release-0-72/</id>
    <title type="html">Jim Tcl version 0.72</title>
    <published>2011-10-05T14:00:00Z</published>
    <updated>2011-10-05T14:00:00Z</updated>
    <link rel="alternate" href="http://jim.berlios.de/articles/jim-release-0-72/"/>
    <content type="html">&lt;h2 id="announce-jim-tcl-version-072"&gt;ANNOUNCE: Jim Tcl version 0.72&lt;/h2&gt;

&lt;p&gt;Jim Tcl 0.72 has been released and is available from: &lt;/p&gt;

&lt;p&gt;&lt;a href="http://repo.or.cz/w/jimtcl.git"&gt;http://repo.or.cz/w/jimtcl.git&lt;/a&gt; or &lt;a href="https://github.com/msteveb/jimtcl"&gt;https://github.com/msteveb/jimtcl&lt;/a&gt;&lt;/p&gt;

&lt;h2 id="changes-since-version-071"&gt;CHANGES SINCE VERSION 0.71&lt;/h2&gt;

&lt;p&gt;This release incorporates bug fixes and many new features.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bugs fixed in version 0.72&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Improvements to configure (autosetup)&lt;/li&gt;
  &lt;li&gt;Fix memory overwrite in built-in regexp&lt;/li&gt;
  &lt;li&gt;[regexp], [regsub] could leak objects in some circumstances&lt;/li&gt;
  &lt;li&gt;Fix [file join] in some cases&lt;/li&gt;
  &lt;li&gt;[info nameofexecutable] now always returns an absolute path&lt;/li&gt;
  &lt;li&gt;[catch] works correctly for platforms without long long&lt;/li&gt;
  &lt;li&gt;[dict unset] no longer gives an error on missing last key&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Features added in version 0.72&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;[proc] now accepts optional parameters and &amp;ldquo;args&amp;rdquo; in any position&lt;/li&gt;
  &lt;li&gt;Much improved support for mingw32 including 64-bit mingw
    &lt;ul&gt;
      &lt;li&gt;tcl_platform(platform) is set to &amp;ldquo;windows&amp;rdquo;&lt;/li&gt;
      &lt;li&gt;[file dirname] handles leading drive (e.g. c:/)&lt;/li&gt;
      &lt;li&gt;[pwd] returns a path containing only forward slashes&lt;/li&gt;
      &lt;li&gt;[glob] now works correctly&lt;/li&gt;
      &lt;li&gt;[exec] is now fully implement on mingw32&lt;/li&gt;
      &lt;li&gt;Command line editing now works in the win32 console&lt;/li&gt;
      &lt;li&gt;New tcl_platform(pathSeparator)&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Builtin regexp is more efficient. Patterns are only compiled once.&lt;/li&gt;
  &lt;li&gt;Add rand(), srand() and pow() math functions&lt;/li&gt;
  &lt;li&gt;[file delete] now supports the -force option&lt;/li&gt;
  &lt;li&gt;[fconfigure -translation] is now accepted and ignored for Tcl compatibility&lt;/li&gt;
  &lt;li&gt;Improved diagnostics when sourcing a script with missing/mismatches brackets, quotes, etc.&lt;/li&gt;
  &lt;li&gt;Jim Tcl now builds on Haiku (BeOS clone) and Solaris&lt;/li&gt;
  &lt;li&gt;Build now works with BSD make&lt;/li&gt;
  &lt;li&gt;[file mtime] can now set the file time&lt;/li&gt;
  &lt;li&gt;New [aio listen] to set the size of the listen queue on server sockets&lt;/li&gt;
  &lt;li&gt;Jim Tcl Manual is better formatted, commands are hyperlinked and various corrections have been made&lt;/li&gt;
  &lt;li&gt;The oo, tree, binary and pack extensions are now documented&lt;/li&gt;
  &lt;li&gt;New metakit extension&lt;/li&gt;
  &lt;li&gt;The SDL extension once again builds and runs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Steve Bennett (&lt;a href="&amp;#109;&amp;#097;&amp;#105;&amp;#108;&amp;#116;&amp;#111;:&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;"&gt;&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;&lt;/a&gt;)&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:jim.berlios.de,2011-10-04:/articles/jim-sqlite-shell/</id>
    <title type="html">jSQLsh - Jim Tcl SQLite Shell</title>
    <published>2011-10-03T14:00:00Z</published>
    <updated>2011-10-03T14:00:00Z</updated>
    <link rel="alternate" href="http://jim.berlios.de/articles/jim-sqlite-shell/"/>
    <content type="html">&lt;p&gt;The jSQLsh project at &lt;a href="https://github.com/LStinson/jSQLsh"&gt;https://github.com/LStinson/jSQLsh&lt;/a&gt; provides
a small but powerful shell for sqlite, modelled after
&lt;a href="http://www.postgresql.org/docs/9.0/static/app-psql.html"&gt;psql&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The creator, Lorance Stinson, wanted an sqlite command shell which
addressed some of the deficiencies of the native sqlite command
shell, so he decided to create his own with Jim Tcl.&lt;/p&gt;

&lt;p&gt;To run it, you simply need &lt;code&gt;jimsh&lt;/code&gt; built with &lt;em&gt;sqlite3&lt;/em&gt; and &lt;em&gt;readline&lt;/em&gt; support.
For example, to build a version of &lt;code&gt;jimsh&lt;/code&gt; with these extensions included statically:&lt;/p&gt;

&lt;pre class="sh_unix"&gt;
$ ./configure --with-ext="sqlite3 rlprompt"
...
$ make
...
&lt;/pre&gt;

&lt;p&gt;And then try it out:&lt;/p&gt;

&lt;pre class="sh_unix"&gt;
$ ./jimsh jsqlsh
Welcome to the SQLite Shell in Jim TCL 0.72.
Opening the database ':memory:'.
To execute a query type '/'. For help type '/h'.
:memory: (0 rows, 0 changes) # /h
Commands:
  /A(UTO)     Toggle the auto option state.
  /c(lear)    Clear the query buffer
  /D(EBUG)    Toggle the debug option state.
  /d          Display all objects in the database.
  /d[itv]     Display all indexes (/di) / tables (/dt) / views (/dv).
  /d OBJ      Describe the object OBJ.
  /ds OBJ     Displays the schema for the object OBJ.
  /e(dit)     Edit the query buffer.
  /go | /     Execute the query in the query buffer.
  /h(elp)     Print this help text.
  /o(pen)     Open a database file, change directories and list files.
  /P(AGER)    Toggle the page option state.
  /p(rint)    Print the query buffer.
  /s(et)      Set/List configuration options. '/s OPTION VALUE'
              Values are treated as TCL strings and can be quoted.
  /Q(uiet)    Toggle the quiet option state.
  /q(uit)     Quit  (Also Ctrl-D)
  /u(ser)     Display the user macros.
  /u(ser)#    Copy user macro # into the query buffer.
  /u(ser)# -  Copy the query buffer, or supplied text, into macro #.
:memory: (0 rows, 0 changes) # 
&lt;/pre&gt;

&lt;p&gt;Steve Bennett (&lt;a href="&amp;#109;&amp;#097;&amp;#105;&amp;#108;&amp;#116;&amp;#111;:&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;"&gt;&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;&lt;/a&gt;)&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:jim.berlios.de,2011-09-06:/articles/metakit-extension/</id>
    <title type="html">New Metakit Extension</title>
    <published>2011-09-05T14:00:00Z</published>
    <updated>2011-09-05T14:00:00Z</updated>
    <link rel="alternate" href="http://jim.berlios.de/articles/metakit-extension/"/>
    <content type="html">&lt;p&gt;Alexander Shpilkin has contributed the metakit extension to Jim Tcl.&lt;/p&gt;

&lt;p&gt;Metakit (&lt;a href="http://equi4.com/metakit/"&gt;http://equi4.com/metakit/&lt;/a&gt;) is an embeddable non-SQL
database with advanced data manipulation features through the use of views.
Using metakit can be an alternative to sqlite.&lt;/p&gt;

&lt;p&gt;The Jim Tcl metakit interface is different from the Tcl metakit interface as it
makes use of unique Jim Tcl features such as references. The &lt;a href="/documentation/metakit/"&gt;metakit extension&lt;/a&gt;
documentation fully explains the API.&lt;/p&gt;

&lt;h2 id="building-the-metakit-extension"&gt;Building the Metakit Extension&lt;/h2&gt;

&lt;p&gt;Building the extension requires the metakit headers and library to be
available. Here is one way to statically build the metakit extension into jimsh.&lt;/p&gt;

&lt;pre class="sh_unix"&gt;
$ cd jimtcl
$ svn co svn://svn.equi4.com/metakit/trunk metakit
$ cd metakit/unix
$ ./configure --without-tcl --without-python --disable-shared
$ make
$ cd ../..
$ ./configure --with-ext=mk CFLAGS="-Imetakit/include -Lmetakit/unix"
$ make
$ ./jimsh examples/metakit.tcl
  ...
&lt;/pre&gt;

&lt;p&gt;Steve Bennett (&lt;a href="&amp;#109;&amp;#097;&amp;#105;&amp;#108;&amp;#116;&amp;#111;:&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;"&gt;&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;&lt;/a&gt;)&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:jim.berlios.de,2011-06-24:/articles/jim-release-0-71/</id>
    <title type="html">Jim Tcl version 0.71</title>
    <published>2011-06-23T14:00:00Z</published>
    <updated>2011-06-23T14:00:00Z</updated>
    <link rel="alternate" href="http://jim.berlios.de/articles/jim-release-0-71/"/>
    <content type="html">&lt;h2 id="announce-jim-tcl-version-071"&gt;ANNOUNCE: Jim Tcl version 0.71&lt;/h2&gt;

&lt;p&gt;Jim Tcl 0.71 has been released and is available from: &lt;/p&gt;

&lt;p&gt;&lt;a href="http://repo.or.cz/w/jimtcl.git"&gt;http://repo.or.cz/w/jimtcl.git&lt;/a&gt; or &lt;a href="https://github.com/msteveb/jimtcl"&gt;https://github.com/msteveb/jimtcl&lt;/a&gt;&lt;/p&gt;

&lt;h2 id="changes-since-version-070"&gt;CHANGES SINCE VERSION 0.70&lt;/h2&gt;

&lt;p&gt;This release incorporates bug fixes and
several new features, including:&lt;/p&gt;

&lt;p&gt;Bugs fixed&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Line editing works better on serial consoles&lt;/li&gt;
  &lt;li&gt;Fix various parsing bugs and crashes in unusual cases&lt;/li&gt;
  &lt;li&gt;package require now loads packages at the global level&lt;/li&gt;
  &lt;li&gt;string trim* and string last are now 8-bit clean and faster&lt;/li&gt;
  &lt;li&gt;exec child processes are now reaped&lt;/li&gt;
  &lt;li&gt;FD_CLOEXEC is now set on opened filehandles&lt;/li&gt;
  &lt;li&gt;dlopen() handles are now freed on freeing interpreter&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Features added&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Add optional support for the binary command&lt;/li&gt;
  &lt;li&gt;Test suite is now tcltests v2 compatible&lt;/li&gt;
  &lt;li&gt;proc &amp;lsquo;args&amp;rsquo; can now be renamed&lt;/li&gt;
  &lt;li&gt;Automatic proc upref args are now supported with &amp;amp;varname&lt;/li&gt;
  &lt;li&gt;expr shorthand syntax with $(&amp;hellip;)&lt;/li&gt;
  &lt;li&gt;Previous proc definitions can be saved with local and invoked with upcall&lt;/li&gt;
  &lt;li&gt;Non-greedy regexp/regsub support with the built-in regexp implementation&lt;/li&gt;
  &lt;li&gt;Minimal exec implementation is supported even without vfork/waitpid&lt;/li&gt;
  &lt;li&gt;configure is now faster and simpler with autosetup (&lt;a href="https://github.com/msteveb/autosetup"&gt;https://github.com/msteveb/autosetup&lt;/a&gt;)&lt;/li&gt;
  &lt;li&gt;Add string byterange&lt;/li&gt;
  &lt;li&gt;Ability to create a single source file bootstrap jimsh&lt;/li&gt;
  &lt;li&gt;Added debian packaging support&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Steve Bennett (&lt;a href="&amp;#109;&amp;#097;&amp;#105;&amp;#108;&amp;#116;&amp;#111;:&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;"&gt;&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;&lt;/a&gt;)&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:jim.berlios.de,2011-06-10:/articles/new-comment-system/</id>
    <title type="html">New Comment System</title>
    <published>2011-06-09T14:00:00Z</published>
    <updated>2011-06-09T14:00:00Z</updated>
    <link rel="alternate" href="http://jim.berlios.de/articles/new-comment-system/"/>
    <content type="html">&lt;p&gt;I have added a comment system to the Jim Tcl website.
Let me know if there are any problems with it.&lt;/p&gt;

&lt;p&gt;Steve Bennett (&lt;a href="&amp;#109;&amp;#097;&amp;#105;&amp;#108;&amp;#116;&amp;#111;:&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;"&gt;&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;&lt;/a&gt;)&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:jim.berlios.de,2011-06-09:/articles/bootstrap-jimsh/</id>
    <title type="html">Bootstrap jimsh</title>
    <published>2011-06-08T14:00:00Z</published>
    <updated>2011-06-08T14:00:00Z</updated>
    <link rel="alternate" href="http://jim.berlios.de/articles/bootstrap-jimsh/"/>
    <content type="html">&lt;p&gt;The Jim interpreter is small, portable and full-featured. This makes
&lt;code&gt;jimsh&lt;/code&gt; an ideal tool to bootstrap a development system that
requires an interpreter.&lt;/p&gt;

&lt;p&gt;Consider the case of a development configuration system such as
&lt;a href="http://www.gnu.org/software/autoconf/"&gt;GNU autotools&lt;/a&gt;.  Here it
is necessary to run fairly complex scripts that invoke external
programs (such as the compiler) and perform intensive string
processing. The autotools solution uses a combination of &lt;a href="http://en.wikipedia.org/wiki/Bourne_shell"&gt;Bourne
Shell&lt;/a&gt;, the &lt;a href="http://www.gnu.org/software/m4/"&gt;m4 Macro
Processor&lt;/a&gt; and various external
tools such as &lt;code&gt;sed&lt;/code&gt;. Since this needs to work across a wide range
of systems, even those with buggy shells or external tools, many
contortions are required.  The resulting system is
&lt;a href="http://freshmeat.net/articles/stop-the-autoconf-insanity-why-we-need-a-new-build-system"&gt;slow, cumbersome and complex&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now consider the different approach taken by
&lt;a href="http://msteveb.github.com/autosetup/"&gt;autosetup&lt;/a&gt;.  Here a scripting
language is used that has excellent support for string processing,
data structures (arrays/dicts and lists) and running external
programs &amp;mdash; Tcl. The only problem is bootstrap. What if the target
system doesn&amp;rsquo;t have a suitable Tcl interpreter available?  The
solution is a bootstrap version of Jim Tcl is included in the
distribution as a &lt;strong&gt;single source file&lt;/strong&gt; and simply requires a C compiler
to create the interpreter.  In fact, autosetup automatically
determines if no suitable and interpreter is available and seamlessly
builds and runs the bootstrap interpreter.&lt;/p&gt;

&lt;pre class="sh_unix"&gt;
$ ./configure 
No installed jimsh or tclsh, building local bootstrap jimsh0
Host System...x86_64-apple-darwin10.7.0
Build System...x86_64-apple-darwin10.7.0
C compiler...ccache cc -g -O2
C++ compiler...ccache c++ -g -O2
Checking for stdlib.h...ok
...
&lt;/pre&gt;

&lt;p&gt;A script to create the bootstrap interpreter source is included in the
&lt;a href="http://repo.or.cz/w/jimtcl.git/blob/HEAD:/make-bootstrap-jim"&gt;jimtcl git repository&lt;/a&gt;&lt;/p&gt;

&lt;pre class="sh_unix"&gt;
$ sh make-bootstrap-jim &amp;gt;jimsh0.c
$ time cc -o jimsh0 jimsh0.c
real   0m1.339s
user   0m1.121s
sys    0m0.109s
$ ./jimsh0
Welcome to Jim version 0.71
. 
&lt;/pre&gt;

&lt;p&gt;Steve Bennett (&lt;a href="&amp;#109;&amp;#097;&amp;#105;&amp;#108;&amp;#116;&amp;#111;:&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;"&gt;&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;&lt;/a&gt;)&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:jim.berlios.de,2011-05-26:/articles/no-namespaces/</id>
    <title type="html">Coping without Namespaces</title>
    <published>2011-05-25T14:00:00Z</published>
    <updated>2011-05-25T14:00:00Z</updated>
    <link rel="alternate" href="http://jim.berlios.de/articles/no-namespaces/"/>
    <content type="html">&lt;p&gt;One of the features of Tcl which Jim lacks is support for
&lt;a href="http://www.tcl.tk/man/tcl8.5/TclCmd/namespace.htm"&gt;namespaces&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The lack of namespaces in Jim is generally not a problem in the
small, embedded applications for which Jim is most suited. However
occasionally it useful to be able to port Tcl code which uses
namespace.  For example, &lt;a href="http://tcllib.sourceforge.net/"&gt;tcllib&lt;/a&gt;
makes heavy use of namespaces. This article describes one approach
to easily porting this code to Jim.&lt;/p&gt;

&lt;p&gt;For this example, we will port &lt;a href="http://tcllib.cvs.sourceforge.net/viewvc/tcllib/tcllib/modules/dns/dns.tcl"&gt;dns.tcl&lt;/a&gt; to Jim.&lt;/p&gt;

&lt;p&gt;The general approach is to modify the code from using implicit scoping to explicit scoping.
Consider the following code which uses namespaces to declare a proc and a variable within a namespace.&lt;/p&gt;

&lt;pre class="sh_tcl"&gt;
namespace eval dns {
	variable timeout 10 
	proc configure {new} {
		variable timeout
		set timeout $new
	}
}
&lt;/pre&gt;

&lt;p&gt;This code create a variable &lt;code&gt;::dns::timeout&lt;/code&gt; and a proc &lt;code&gt;::dns::configure&lt;/code&gt;. We can do the same
explicitly.&lt;/p&gt;

&lt;pre class="sh_tcl"&gt;
set dns::timeout 10

proc dns::configure {new} {
	global dns::timeout
	set dns::timeout $new
}
&lt;/pre&gt;

&lt;p&gt;The main differences between this code and the namespace code are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;All variables and procs are visible, even if not &lt;em&gt;exported&lt;/em&gt;&lt;/li&gt;
  &lt;li&gt;Namespace procs need to be referenced with a fully qualified name&lt;/li&gt;
  &lt;li&gt;Namespace variables need to be referenced with a fully qualified name&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can mitigate this last difference with one small change.&lt;/p&gt;

&lt;pre class="sh_tcl"&gt;
# Poor man's variable for Jim Tcl
# Links a global variable, ::ns::var to a local variable, var
proc variable {ns var} {
    uplevel 1 [list upvar #0 ${ns}::$var $var]
}

set dns::timeout 10

proc dns::configure {new} {
	variable dns timeout
	set timeout $new
}
&lt;/pre&gt;

&lt;p&gt;With this change, code can refer to the unqualified variable name
which is linked to the fully qualified name.&lt;/p&gt;

&lt;p&gt;You can see the fully converted version of &lt;a href="https://github.com/msteveb/jimtcl/blob/0.73/examples/dns.tcl"&gt;dns.tcl for Jim&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To summarise:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Remove &lt;code&gt;namespace eval&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Initialise variables with fully qualified names: &lt;code&gt;set ns::var value&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Ensure procs are declared with fully quality names: &lt;code&gt;proc ns::procname { ... }&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Use fully qualified names when invoking procs within the namespace.&lt;/li&gt;
  &lt;li&gt;Replace the use of &lt;code&gt;namespace current&lt;/code&gt; with the namespace name&lt;/li&gt;
  &lt;li&gt;Replace the use of &lt;code&gt;namespace origin&lt;/code&gt; with the namespace name&lt;/li&gt;
  &lt;li&gt;Use the &lt;code&gt;variable&lt;/code&gt; proc to declare variables within procs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Steve Bennett (&lt;a href="&amp;#109;&amp;#097;&amp;#105;&amp;#108;&amp;#116;&amp;#111;:&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;"&gt;&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;&lt;/a&gt;)&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:jim.berlios.de,2011-05-25:/articles/jim-is-modular/</id>
    <title type="html">Jim Is Modular</title>
    <published>2011-05-24T14:00:00Z</published>
    <updated>2011-05-24T14:00:00Z</updated>
    <link rel="alternate" href="http://jim.berlios.de/articles/jim-is-modular/"/>
    <content type="html">&lt;p&gt;One of the advantages of Jim Tcl is that the core interpreter
contains only the bare essentials. Many Tcl standard commands are provided by
optional extensions which can be disable or built as loadable modules if required.&lt;/p&gt;

&lt;dl&gt;
  &lt;dt&gt;core commands&lt;/dt&gt;
  &lt;dd&gt;*, +, -, /, alias, append, break, catch, collect, concat,
continue, curry, dict, env, error, errorInfo, eval, exists, exit,
expr, finalize, for, foreach, format, getref, global, if, incr,
info, join, lambda, lappend, lassign, lindex, linsert, list, llength,
lmap, local, lrange, lrepeat, lreplace, lreverse, lsearch, lset,
lsort, proc, rand, range, ref, rename, return, scan, set, setref,
source, split, stackdump, stacktrace, string, subst, switch, tailcall,
tell, throw, time, unset, uplevel, upvar, while&lt;/dd&gt;
  &lt;dt&gt;aio extension&lt;/dt&gt;
  &lt;dd&gt;open, socket&lt;/dd&gt;
  &lt;dt&gt;eventloop extension&lt;/dt&gt;
  &lt;dd&gt;vwait, update, after&lt;/dd&gt;
  &lt;dt&gt;tclcompat extension&lt;/dt&gt;
  &lt;dd&gt;puts, gets, read, close, tell, seek, eof, flush, parray, try, throw, case&lt;/dd&gt;
  &lt;dt&gt;array extension&lt;/dt&gt;
  &lt;dd&gt;array&lt;/dd&gt;
  &lt;dt&gt;clock extension&lt;/dt&gt;
  &lt;dd&gt;clock&lt;/dd&gt;
  &lt;dt&gt;file extension&lt;/dt&gt;
  &lt;dd&gt;file, cd, pwd&lt;/dd&gt;
  &lt;dt&gt;exec extension&lt;/dt&gt;
  &lt;dd&gt;exec&lt;/dd&gt;
  &lt;dt&gt;load extension&lt;/dt&gt;
  &lt;dd&gt;load&lt;/dd&gt;
  &lt;dt&gt;package extension&lt;/dt&gt;
  &lt;dd&gt;package&lt;/dd&gt;
  &lt;dt&gt;posix extension&lt;/dt&gt;
  &lt;dd&gt;os.fork, os.wait, os.getids, os.gethostname, os.uptime, pid&lt;/dd&gt;
  &lt;dt&gt;glob, readdir extensions&lt;/dt&gt;
  &lt;dd&gt;glob, readdir&lt;/dd&gt;
  &lt;dt&gt;regexp extension&lt;/dt&gt;
  &lt;dd&gt;regexp, regsub&lt;/dd&gt;
  &lt;dt&gt;signal extension&lt;/dt&gt;
  &lt;dd&gt;signal, alarm, kill, sleep&lt;/dd&gt;
&lt;/dl&gt;

&lt;p&gt;In addition, features including references, UTF-8 support, IPv6 and command line editing
can be disabled with &lt;code&gt;configure&lt;/code&gt;. See &lt;code&gt;configure --help&lt;/code&gt; for full details.&lt;/p&gt;

&lt;p&gt;Steve Bennett (&lt;a href="&amp;#109;&amp;#097;&amp;#105;&amp;#108;&amp;#116;&amp;#111;:&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;"&gt;&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;&lt;/a&gt;)&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:jim.berlios.de,2011-04-24:/articles/2011-04-24/</id>
    <title type="html">New Website Launched</title>
    <published>2011-04-23T14:00:00Z</published>
    <updated>2011-04-23T14:00:00Z</updated>
    <link rel="alternate" href="http://jim.berlios.de/articles/2011-04-24/"/>
    <content type="html">&lt;p&gt;Jim Tcl development has been proceeding apace, but the &lt;a href="http://jim.berlios.de/"&gt;website&lt;/a&gt;
had not been updated for several years. In order to make Jim Tcl
more approachable, we have given the website and updated the content
to reflect current reality.&lt;/p&gt;

&lt;p&gt;Steve Bennett (&lt;a href="&amp;#109;&amp;#097;&amp;#105;&amp;#108;&amp;#116;&amp;#111;:&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;"&gt;&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;&lt;/a&gt;)&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:jim.berlios.de,2011-04-22:/articles/2011-04-22/</id>
    <title type="html">Roadmap for Jim Tcl</title>
    <published>2011-04-21T14:00:00Z</published>
    <updated>2011-04-21T14:00:00Z</updated>
    <link rel="alternate" href="http://jim.berlios.de/articles/2011-04-22/"/>
    <content type="html">&lt;p&gt;I have a few things on my list that I would like to see go into the
next release of Jim Tcl.&lt;/p&gt;

&lt;h2 id="boring-stuff"&gt;Boring Stuff&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Bug fixes&lt;/li&gt;
  &lt;li&gt;Performance improvements&lt;/li&gt;
  &lt;li&gt;Size reduction&lt;/li&gt;
  &lt;li&gt;Clean up dlopen() handles on interpreter deletion&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="tcl-8x-features"&gt;Tcl 8.x Features&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Add support for the [binary] command&lt;/li&gt;
  &lt;li&gt;Support for non-greedy quantifiers in [regexp]&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="tclx-features"&gt;TclX Features&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Add the [loop] command&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="tcl-9-proposed-features"&gt;Tcl 9 (Proposed) Features&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;[expr] shorthand syntax: $(&amp;hellip;)&lt;/li&gt;
  &lt;li&gt;Automatic upvars in prog args: &amp;amp;varname&lt;/li&gt;
  &lt;li&gt;Allow proc &amp;lsquo;args&amp;rsquo; to be renamed&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="build-system"&gt;Build System&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Replace autoconf with Tcl-based autosetup (&lt;a href="https://github.com/msteveb/autosetup"&gt;https://github.com/msteveb/autosetup&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id="other-enhancements"&gt;Other Enhancements&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;Ability to &amp;ldquo;push&amp;rdquo; a proc over the top of an existing proc to easily create a
wrapper proc, including the ability to &amp;ldquo;upcall&amp;rdquo; the original proc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Steve Bennett (&lt;a href="&amp;#109;&amp;#097;&amp;#105;&amp;#108;&amp;#116;&amp;#111;:&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;"&gt;&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;&lt;/a&gt;)&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:jim.berlios.de,2011-04-14:/articles/2011-04-14/</id>
    <title type="html">Announcing Jim Tcl version 0.70</title>
    <published>2011-04-13T14:00:00Z</published>
    <updated>2011-04-13T14:00:00Z</updated>
    <link rel="alternate" href="http://jim.berlios.de/articles/2011-04-14/"/>
    <content type="html">&lt;p&gt;Jim Tcl 0.70 has been released and is available from: &lt;/p&gt;

&lt;p&gt;&lt;a href="http://repo.or.cz/w/jimtcl.git"&gt;http://repo.or.cz/w/jimtcl.git&lt;/a&gt;
or &lt;a href="https://github.com/msteveb/jimtcl"&gt;https://github.com/msteveb/jimtcl&lt;/a&gt;&lt;/p&gt;

&lt;h2 id="changes-since-version-063"&gt;CHANGES SINCE VERSION 0.63&lt;/h2&gt;

&lt;p&gt;This is a major update which incorporates many bug fixes and
several new features, including:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Optional UTF-8 support&lt;/li&gt;
  &lt;li&gt;Optional built-in regexp engines for better Tcl compatibility and UTF-8 support&lt;/li&gt;
  &lt;li&gt;Command line editing with linenoise&lt;/li&gt;
  &lt;li&gt;Pure-Tcl OO extension &lt;/li&gt;
  &lt;li&gt;exec uses only vfork() for full functionality on no-mmu uClinux&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Steve Bennett (&lt;a href="&amp;#109;&amp;#097;&amp;#105;&amp;#108;&amp;#116;&amp;#111;:&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;"&gt;&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;&lt;/a&gt;)&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:jim.berlios.de,2010-11-24:/articles/2010-11-24/</id>
    <title type="html">A History of Jim</title>
    <published>2010-11-23T14:00:00Z</published>
    <updated>2010-11-23T14:00:00Z</updated>
    <link rel="alternate" href="http://jim.berlios.de/articles/2010-11-24/"/>
    <content type="html">&lt;p&gt;&lt;a href="/img/jim-history-chart.pdf"&gt;&lt;img src="/img/jim-history-thumb.png" /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I intend to analyse the history of Jim in more detail at some point.
Nonetheless, this is interesting. For this exercise I attempted to
build and run benchmarks for every, single version of Jim.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Click on the image for a larger version.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Steve Bennett (&lt;a href="&amp;#109;&amp;#097;&amp;#105;&amp;#108;&amp;#116;&amp;#111;:&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;"&gt;&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;&lt;/a&gt;)&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:jim.berlios.de,2010-11-15:/articles/2010-11-15/</id>
    <title type="html">IPv6 Support</title>
    <published>2010-11-14T14:00:00Z</published>
    <updated>2010-11-14T14:00:00Z</updated>
    <link rel="alternate" href="http://jim.berlios.de/articles/2010-11-15/"/>
    <content type="html">&lt;p&gt;Jim Tcl has had ipv6 support ever since the WorkWare fork was merged
back into mainline.&lt;/p&gt;

&lt;p&gt;You can read more about it in the documentation at:
&lt;a href="http://repo.or.cz/w/jimtcl.git/blob_plain/master:/Tcl_shipped.html#_socket"&gt;socket&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Basically it is a matter of specifying &lt;code&gt;-ipv6&lt;/code&gt; when creating the
socket and giving an IPv6 address. For example:&lt;/p&gt;

&lt;pre class="sh_tcl"&gt;
set s [socket -ipv6 stream.server {[::]:2000}]
&lt;/pre&gt;

&lt;p&gt;Note that IPv6 addresses are enclosed in square brackets. This is
the same notation used for IPv6 URLs and makes it easy to keep the
address:port syntax.&lt;/p&gt;

&lt;p&gt;The address returned by &lt;code&gt;recvfrom&lt;/code&gt; will be formatted appropriately, so it can be used directly by &lt;code&gt;sendto&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Some simple IPv6 examples are included in the repository. For example: &lt;a href="http://repo.or.cz/w/jimtcl.git/blob_plain/master:/examples/udp6.server"&gt;udp6.server&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that on all hosts I have tried, listening on an IPv6 socket
will also listen on the corresponding IPv4 socket. You can try this
by running udp6.server and connecting with both udp6.client and
udp.client&lt;/p&gt;

&lt;p&gt;Steve Bennett (&lt;a href="&amp;#109;&amp;#097;&amp;#105;&amp;#108;&amp;#116;&amp;#111;:&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;"&gt;&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;&lt;/a&gt;)&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:jim.berlios.de,2010-11-03:/articles/2010-11-03/</id>
    <title type="html">expr shorthand syntax</title>
    <published>2010-11-02T14:00:00Z</published>
    <updated>2010-11-02T14:00:00Z</updated>
    <link rel="alternate" href="http://jim.berlios.de/articles/2010-11-03/"/>
    <content type="html">&lt;p&gt;One of the biggest complaints about Tcl is it&#8217;s verbosity for common expressions. Consider:&lt;/p&gt;

&lt;pre class="sh_tcl"&gt;
set sublist [lrange $list [expr {$a + 1}] [expr {$b - 1}]]
&lt;/pre&gt;

&lt;p&gt;This is mitigated somewhat in list and string index and ranges
expression which support the notation &lt;code&gt;int+int&lt;/code&gt; or &lt;code&gt;int-int&lt;/code&gt;. However,
many simple, common expressions are still cumbersome.&lt;/p&gt;

&lt;p&gt;There has been much &lt;a href="http://wiki.tcl.tk/8389"&gt;discussion&lt;/a&gt; about
shorthand notation for expr, however as for many things with Tcl,
progress is slow or non-existent.&lt;/p&gt;

&lt;p&gt;There is no need to suffer the same fate for Jim, though. So I
implemented a trivial patch to support the syntax &lt;code&gt;$(...)&lt;/code&gt; as a
shorthand for expr.  Let&#8217;s see how it looks:&lt;/p&gt;

&lt;pre class="sh_tcl"&gt;
. set x $(3 + 4)
7
. incr y $(7 * [incr x])
56
. set z $("bb" in {aa bb cc})
1
&lt;/pre&gt;

&lt;p&gt;A lot better! Essentially avoiding one set of brackets plus the
command name. Currently in Tcl, &lt;code&gt;$(...)&lt;/code&gt; is an accidental valid
expression, accessing an array named with the empty string. Giving
up this is a very small price to pay for this more accessible syntax.
Perhaps as Tcl grinds it&#8217;s way towards version 9.0, it could give
up a tiny bit of backward compatibility for easy of use.&lt;/p&gt;

&lt;p&gt;Steve Bennett (&lt;a href="&amp;#109;&amp;#097;&amp;#105;&amp;#108;&amp;#116;&amp;#111;:&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;"&gt;&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;&lt;/a&gt;)&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:jim.berlios.de,2010-10-29:/articles/2010-10-29/</id>
    <title type="html">Announcing Jim Tcl version 0.63</title>
    <published>2010-10-28T14:00:00Z</published>
    <updated>2010-10-28T14:00:00Z</updated>
    <link rel="alternate" href="http://jim.berlios.de/articles/2010-10-29/"/>
    <content type="html">&lt;p&gt;Jim Tcl 0.63 has been released and is available from: &lt;/p&gt;

&lt;p&gt;&lt;a href="http://repo.or.cz/w/jimtcl.git"&gt;http://repo.or.cz/w/jimtcl.git&lt;/a&gt;&lt;/p&gt;

&lt;h2 id="changes-since-version-051"&gt;CHANGES SINCE VERSION 0.51&lt;/h2&gt;

&lt;p&gt;This is a major update which incorporates many bug fixes and new features.&lt;/p&gt;

&lt;p&gt;Some of the new features over Jim 0.51 include:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Now includes comprehensive documentation
See: &lt;a href="http://repo.or.cz/w/jimtcl.git/blob_plain/HEAD:/Tcl_shipped.html"&gt;Tcl_Shipped.html&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Now includes extensive unit tests&lt;/li&gt;
  &lt;li&gt;Far better tracking of source location, including &amp;lsquo;info source&amp;rsquo;, &amp;lsquo;stacktrace&amp;rsquo; and &amp;lsquo;stackdump&amp;rsquo;&lt;/li&gt;
  &lt;li&gt;Networking support includes IPv6, working UDP support, &amp;lsquo;socket pipe&amp;rsquo;&lt;/li&gt;
  &lt;li&gt;Many bug fixes and improvements in &amp;lsquo;expr&amp;rsquo;&lt;/li&gt;
  &lt;li&gt;&amp;lsquo;exec&amp;rsquo; improvements including redirection options and respect for $::env&lt;/li&gt;
  &lt;li&gt;Full &amp;lsquo;configure&amp;rsquo; support for static extensions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Some notable differences include:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;aio.open and aio.socket are now plain &amp;lsquo;open&amp;rsquo; and &amp;lsquo;socket&amp;rsquo;&lt;/li&gt;
  &lt;li&gt;&amp;lsquo;proc&amp;rsquo; now returns the name of the procedure&lt;/li&gt;
  &lt;li&gt;Changes to the package system and extension interface&lt;/li&gt;
  &lt;li&gt;&amp;lsquo;jim&amp;rsquo; is now &amp;lsquo;jimsh&amp;rsquo;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Steve Bennett (&lt;a href="&amp;#109;&amp;#097;&amp;#105;&amp;#108;&amp;#116;&amp;#111;:&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;"&gt;&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;&lt;/a&gt;)&lt;/p&gt;
</content>
  </entry>
  <entry>
    <id>tag:jim.berlios.de,2010-09-09:/articles/2010-09-09/</id>
    <title type="html">SMTP Mail with Jim</title>
    <published>2010-09-08T14:00:00Z</published>
    <updated>2010-09-08T14:00:00Z</updated>
    <link rel="alternate" href="http://jim.berlios.de/articles/2010-09-09/"/>
    <content type="html">&lt;p&gt;I recently had the need to send email from my Jim-enabled embedded
web application. There are many ways to achieve this, including via
a command line application, but I chose to use the networking
capabilities of Jim to send email directly via SMTP. It turned out
to be remarkably easy.&lt;/p&gt;

&lt;p&gt;First the test code:&lt;/p&gt;

&lt;pre class="sh_tcl"&gt;
# Test the smtp package

package require smtp

# Subclass smtp to provide a custom log method
class smtp_log smtp {}

smtp_log method log {msg} {
    puts $msg
}

# Create an instance to send our message
set s [smtp_log new {server mail.workware.net.au}]

# And send it
set result [$s send {
    to steveb@workware.net.au
    from steveb@workware.net.au
    subject "Test message"
    body "hello from steve"
}]
if {$result ne ""} {
    puts "Result is $result"
}
&lt;/pre&gt;

&lt;p&gt;And the result of running it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;&amp;lt;&amp;lt; 220 mail.workware.net.au ESMTP Postfix
&amp;gt;&amp;gt;&amp;gt; HELO stevebmac.internal.workware.net.au
&amp;lt;&amp;lt;&amp;lt; 250 mail.workware.net.au
&amp;gt;&amp;gt;&amp;gt; MAIL FROM: jim@workware.net.au
&amp;lt;&amp;lt;&amp;lt; 250 2.1.0 Ok
&amp;gt;&amp;gt;&amp;gt; RCPT TO: steveb@workware.net.au
&amp;lt;&amp;lt;&amp;lt; 250 2.1.5 Ok
&amp;gt;&amp;gt;&amp;gt; DATA
&amp;lt;&amp;lt;&amp;lt; 354 End data with &amp;lt;CR&amp;gt;&amp;lt;LF&amp;gt;.&amp;lt;CR&amp;gt;&amp;lt;LF&amp;gt;
&amp;gt;&amp;gt;&amp;gt; To: steveb@workware.net.au
&amp;gt;&amp;gt;&amp;gt; From: "Jim Tcl" &amp;lt;jim@workware.net.au&amp;gt;
&amp;gt;&amp;gt;&amp;gt; Date: Fri, 10 Sep 09 2010 14:07:49 +1000
&amp;gt;&amp;gt;&amp;gt; Subject: This is a test email
&amp;gt;&amp;gt;&amp;gt; 
=== sending body
&amp;gt;&amp;gt;&amp;gt; .
&amp;lt;&amp;lt;&amp;lt; 250 2.0.0 Ok: queued as 1DB491E69538A
&amp;gt;&amp;gt;&amp;gt; QUIT
&amp;lt;&amp;lt;&amp;lt; 221 2.0.0 Bye
::: ok
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And here is the smtp package (&lt;code&gt;smtp.tcl&lt;/code&gt;). Note the use of
&lt;code&gt;alarm/signal/catch -signal&lt;/code&gt; to implement the timeout.&lt;/p&gt;

&lt;p&gt;This package is built as an OO class.&lt;/p&gt;

&lt;pre class="sh_tcl"&gt;
# Package supporting sending email via direct SMTP

package require oo

# class to send emails via SMTP
#
# The following class variables are supported
#
# server   - The hostname or IP address of the target SMTP server
#
# And optionally:
# port     - The port to sent to (defaults to 25)
# timeout  - Protocol timeout in seconds (defaults to 10)

class smtp {server {} port 25 timeout 10 sock {}}

# This log method can be overridden either by
# creating a subclass, or just overwriting this method
smtp method log {msg} {}

# Send an email
#
# $info is a dictionary containing the following (required) elements
#
# subject  - The email subject
# to       - Either a simple email address, or a list of {emailaddr name}
# from     - Either a simple email address, or a list of {emailaddr name}
# body     - The newline-separated email body
#
smtp method send {info} {
    if {$server eq ""} {
        return "smtp send: no server specified"
    }

    foreach req {subject to from body} {
        if {![exists info($req)]} {
            return "smtp send: missing $req"
        }
    }

    local proc smtp.format_addr {addr {name {}}} {
        if {$name eq ""} {
            return $addr
        }
        return "\"$name\" &amp;lt;$addr&amp;gt;"
    }

    signal handle SIGALRM

    # Run the protocol
    set rc [catch -signal {
        alarm $timeout
        set sock [socket stream $server:$port]

        $self whenok 220 {
            $self puts "HELO [info hostname]"
        }
        $self whenok 250 {
            $self puts "MAIL FROM: [lindex $info(from) 0]"
        }
        $self whenok 250 {
            $self puts "RCPT TO: [lindex $info(to) 0]"
        }
        $self whenok 250 {
            $self puts "DATA"
        }
        $self whenok 354 {
            $self puts "To: [smtp.format_addr {*}$info(to)]"
            $self puts "From: [smtp.format_addr {*}$info(from)]"
            set RFC822 {%a, %d %b %m %Y %H:%M:%S %z}
            $self puts "Date: [clock format [clock seconds] -format $RFC822]"
            $self puts "Subject: $info(subject)"
            $self puts ""
            $self log "=== sending body"
            foreach line [split $info(body) \n] {
                if {[string index $line 0] eq "."} {
                    $sock puts -nonewline "."
                }
                $sock puts $line\r
            }
            $self puts "."
        }
        $self whenok 250 {
            $self puts "QUIT"
        }
        $self whenok 221 {
            $self log "::: ok"
        }
    } error opts]
    alarm 0

    catch { $sock close }

    if {$rc} {
        $self log "!!! $error"
        return $error
    }
}

# Write to the socket and also log
smtp method puts {msg} {
    $self log "&amp;gt;&amp;gt;&amp;gt; $msg"
    $sock puts $msg\r
    $sock flush
}

# Internal method
#
# When the socket is readable, 
# reads the response and checks the code, and if OK, execute the $script
# If not OK, returns with a 'break' return code and a message
smtp method whenok {code script} {
    alarm $timeout

    if {[$sock gets buf] &amp;lt; 0} {
        return -code break "Expected $code but got EOF"
    }
    $self log "&amp;lt;&amp;lt;&amp;lt; $buf"
    lassign $buf recv
    if {[string range $recv 0 2] ne $code} {
        return -code break "Expected $code but got: $buf"
    }
    # Invoke the script in the original callframe
    uplevel 2 $script
}
&lt;/pre&gt;

&lt;p&gt;Steve Bennett (&lt;a href="&amp;#109;&amp;#097;&amp;#105;&amp;#108;&amp;#116;&amp;#111;:&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;"&gt;&amp;#115;&amp;#116;&amp;#101;&amp;#118;&amp;#101;&amp;#098;&amp;#064;&amp;#119;&amp;#111;&amp;#114;&amp;#107;&amp;#119;&amp;#097;&amp;#114;&amp;#101;&amp;#046;&amp;#110;&amp;#101;&amp;#116;&amp;#046;&amp;#097;&amp;#117;&lt;/a&gt;)&lt;/p&gt;
</content>
  </entry>
</feed>
