[ Home Page ] [ Eiffel Archive ] [ Eiffel Classes and Clusters ]

Arc de Triomphe clipart (2486 bytes)

Tcl-Eiffel: A GUI Extension to SmallEiffel

Written by Joachim Bergmeyer.

tcl-eif.032a.tar.gz (29,674 bytes) - source code
tcl-eif.032a.ps (46,059 bytes) - documentation in Postscript
http://www.elj.com/epan/by_author/jb/tcl-eif/ (Tcl-Eiffel EPAN page)
http://home.pages.de/~jbergmeyer/ (Tcl-Eiffel home page)

Tcl-Eiffel: A GUI Extension to SmallEiffel
by Joachim Bergmeyer <jbergmeyer@bigfoot.de>

Eiffel is an object-oriented language with a distinct focus on security and correctness expressed in the principle of "Design by Contract". SmallEiffel is a free implementation of this language covered by GNU Copyleft. Tcl-Eiffel is an extension to SmallEiffel intended to fill in the missing support of Graphical User Interfaces (GUI) by providing a connection to the wellknown Tcl interpreter and Tk library. This is done by implementing a socket for SmallEiffel and linking an Eiffel program to Tcl/Tk via a socket connection. Tcl-Eiffel itself is free software with the same license as the standard library coming with SmallEiffel.

1. Intentions

1.1 Provide a GUI

Tcl-Eiffel was written to fill the gap within SmallEiffel due to the missing graphical user interface (GUI). After having worked with John Ousterhouts Tcl/Tk earlier, I decided to try to connect this to SmallEiffel. Tcl/Tk has some strengths in building very good looking and working GUIs with incredible little cost of work.

1.2 Create the GUI fast and easy

As this is especially true with tools like vtcl (see Resources section), I decided not to embed Tcl/Tk into Eiffel by writing wrapper classes but to provide a connection to a standalone Wish shell using the basic Tcl feature "socket". This is also a very economic way as writing wrapper classes for every needed Tcl procedure and Tk widget would have been a long and tedious task.

1.3 Run over the net

As a side effect we get the advantage of being able to run the GUI client and the SmallEiffel program (in the following called the server) on different machines as long as there is a standard tcp/ip-based network connection.

1.4 Use Java if you like

As Java is also designed to have strong network capabilities there is no reason why a GUI client should not be written in Java, if one prefers it. But my opinion is that Java is "overkill" in this place because a Tcl/Tk script is fast enough, much more flexible and much easier to create.

2. How it works

2.1 Sockets are portable

After some experiments and two initial working versions based on Embedded Tk I decided to use fewer stuff from foreign sources to improve portability.

I wrote a SOCKET class which is supported by a native C library. This C library uses just the basic *nix socket concept which is available now on many OSes. That should make porting to other OSes easy. My wish is that Tcl-Eiffel becomes available at least on every platform on which Tcl and Tk are present, although even SmallEiffel ports to platforms not supported by Tcl/Tk are useable if there is a host available over the network where the Tcl/Tk GUI can run on.

2.2 Single connections

The Eiffel server has to create an instance of the SOCKET class on a specified port number. The SOCKET creation class SOCKET.connect_to(port:INTEGER) creates an internet stream socket with SOCKET.create_socket(port:INTEGER) and listens on this port for exactly one connection with SOCKET.accept_one. If a connection from a client somewhere on the net arrives then SOCKET.accept_one returns.

As inherited from INPUT_STREAM and OUTPUT_STREAM the SOCKET acts like an usual STD_FILE_READ_WRITE from this moment and can be used like std_input and std_output.

The other end is created as a Tcl socket with "open <host> <port>". This command returns a channel descriptor which can be used similar to a normal file. It is recommended to switch the file mode to non-blocking with "fconfigure" and to install a file event manager with "fileevent" which does the real reading from the channel.

2.3 Define a protocol

You have to provide code which reads from the SOCKET and interpretes the read data as defined by your own protocol, and you have to send something back to Tcl that gets interpreted there in a useful way. Tcl-Eiffel does not provide a special protocol.

Very powerful will be the combination of Tcl-Eiffel with Gobo Eiffel gelex and geyacc, written by Eric Bezault, archived at the Eiffel Forum (see Resources section). Gelex creates a scanner class from a scanner description file which is able to tokenize the data stream arriving over the socket connection. Geyacc creates a parser class from a parser description file. The parser detects the elements of the defined syntax. You have to fill in Eiffel code then to form the according semantic actions.

The easiest and most powerful way to get information back to Tcl is to write a file event manager that evaluates everything coming back from SmallEiffel as a Tcl script. This is demonstrated in the following demo app.

This might also be a security problem if you connect to a remote server whom you cannot trust perfectly, as you cannot be sure to get back only undangerous scripts.

2.4 The "calc" demo

The current demo program "calc" is based on a demo coming with Gobo Eiffel V1.3 and uses no gelex scanner but only a very simple scanner written in Eiffel which copies the read data onto the parser.

Furthermore it sends back everything that has to be shown in the GUI as a Tcl script which is then evaluated by the Tcl interpreter. So if you send back "puts garble", then the result of your calculation will be the output of "garble" on stdout of the Tcl interpreter - nothing special happens, the GUI just does what the server says.

It should be pointed out that you should not send Tcl code to the GUI that calls the server again, because that could end up in an infinite loop of messages rolling back and forth through the socket connection.

2.5 Multiple connections not yet supported

The current design has a limitation: The chosen implementation of the SOCKET class does not support multiple connections. Only one stream is opened on a particular port, intended to link *one* SmallEiffel server process to *his own* Tcl/Tk GUI process.

To change this a select() loop has to be created in the native code part, which in turn calls back to one SmallEiffel object when something arrives on the related port. At every new connection a new object has to be created and to be linked to the newly opened port.

3. Overview of current state

4. Resources

[ Home Page ] [ Eiffel Archive ] [ Eiffel Classes and Clusters ]