In the sample programs seen so far in this article,
Tcl/Tk code in an
ET()
function was used to construct the main window.
This works fine for the examples, since their windows are
uncomplicated and can be constructed with a few lines code.
But in a real application, or even a more complex example,
the amount of Tcl/Tk code needed to initialize the program's windows
can quickly grow to hundreds or thousands of lines.
It is impractical and irksome to put this much code into an
ET()
statement, so the ET system provides another
way to get the job done: the ET_INCLUDE()
statement.
The ET_INCLUDE()
statement is similar in concept to the
#include
statement in the C preprocessor.
Both take a filename as their argument, and both read the named
file into the original source program.
The ET_INCLUDE()
statement expects its file to
be pure Tcl/Tk code, though.
Its job is to turn the Tcl/Tk source into a form that the
C compiler can understand, and to arrange for the Tcl/Tk to
be executed when control reaches the ET_INCLUDE()
statement.
An example may help to clarify this idea.
In the decimal clock program (way back
at the beginning of section 6),
there are 7 lines of Tcl/Tk in an ET()
function used
to create the application's main window.
Now suppose we move those 7 lines of Tcl/Tk into a separate
file named ET()
function with an
ET_INCLUDE()
statement that references the new file
like this:
void main(int argc, char **argv){ Et_Init(&argc, argv); ET_INSTALL_COMMANDS; ET_INCLUDE( dclock.tcl ); Et_MainLoop(); }When the et2c preprocessor sees the
ET_INCLUDE()
statement, it locates the specified file, reads that file into the
C program, and makes arrangements for the text of the file to be
executed as if it had all appeared within an ET()
function.
Well, almost like an ET()
function.
There are a couple of minor differences.
The ET_INCLUDE()
does not understand
the various %s(...)
substitutions as ET()
does.
Also, ET_INCLUDE()
is a true procedure, not a function.
It doesn't return a value like ET()
so
you can't use an ET_INCLUDE()
in an expression.
It is important to understand the difference between an
ET_INCLUDE()
statement like this
ET_INCLUDE( dclock.tcl );and the
source
command of Tcl/Tk, used as follows:
ET( source dclock.tcl );The
ET_INCLUDE()
statement reads the Tcl/Tk into the program at
compile-time, effectively making the Tcl/Tk code part of the executable.
The Tcl source
command, on the other hand, opens and
reads the file at run-time, as the application executes. This
makes the executable a little smaller, but it also means that the
file containing the Tcl/Tk must be available to the executable
whenever it runs.
If you move just the executable, but not the Tcl/Tk file, to
another computer, or even another directory, then it will no
longer work because it won't be able to locate and read the Tcl/Tk file.
The ability to read an external Tcl/Tk script and make it part of the executable program is an important feature of ET. But while you are developing and testing a program, it is sometimes convenient to turn this feature off and to have the application read its scripts at run-time instead of compile-time. That way, you can make changes to the Tcl/Tk script and rerun your program with the changes, but without having to recompile. You can do this using the -dynamic option to the et2c proprocessor. Whenever you run et2c with the -dynamic command-line option, it effective turns instances of the statement
ET_INCLUDE( filename.tcl );into the statement
ET( source filename.tcl );This feature has proven very helpful during development. But be careful to turn it off before doing your final build, or else you won't be able to move your executable to other machines!
There is just one other feature of the ET_INCLUDE()
statement that we need to discuss before moving on, and that is
the algorithm it uses to locate the Tcl/Tk source code files.
Just like the C preprocessor's #include
statement, the
ET_INCLUDE()
mechanism can include
files found in other directories.
The et2c preprocessor always looks first in the working
directory for files named by an ET_INCLUDE()
statement.
If the file is found there, no further search is made.
But if the file is not found, then et2c will also look
in all directories named in -I command line options.
For example, if you run et2c like this:
et2c -I../tcl -I/usr/local/lib/tcl app.c >app_.cand the
ET_INCLUDE( setup.tcl );then et2c will search for the