Tcl is a multiplatform language, running on various Unix systems, Microsoft Windows NT/95/98, and Apple Macintosh. Tcl provides a great deal of machine and operating system independence. If writing portable software is your goal, there are a few areas that still need special attention.
Filenames and pathnames differ among Unix, Windows, and Macintosh. Fortunately, Tcl is happy to work with Unix-style filenames internally. The file command provides help for dealing with filenames when you need to convert between the canonical form and forms required by specific operating systems. You will likely need a native filename if you exec programs that require filenames.
On Unix, the file command takes two or more file pathname components and joins them with the Tcl canonical path delimiter “/”:
file join /home tpoindex src tcl style.tcl
This code produces the following output:
/home/tpoindex/src/tcl/style.tcl
On Windows, the file command takes a pathname in canonical network form and returns the native pathname:
file nativename "/program files/tcl/bin/wish80.exe"
This code produces the following output:
program files clinwish.exe
The file command has many other subcommands to delete, copy, and rename files in an operating system--independent fashion.
Unix, Windows, and Macintosh each have different end of line conventions for text files. In the default state, Tcl is very forgiving in reading files created on a different platform. When writing files to be used on a different system, you should configure the output channel by using the fconfigure command.
For example, if you are creating a file on Unix to be used primarily on a Windows system, use the following code:
set fd [open outfile w] fconfigure $fd -translation crlf puts $fd "hello windows!"
Tcl includes a preset array of platform-specific information
named $tcl_platform
. Elements are shown in the
following table.
| Name of the cpu of the machine |
| Machine word ordering, “bigEndian” or “littleEndian” |
| Name of the operating system |
| Version of the operating system |
| Platform name: “unix”, “windows”, or “macintosh” |
This information can be useful in deciding at runtime how to print a file, execute another program, and so forth.
Reading and writing binary data is always system dependent,
especially native integer and floating-point values. The
binary command provides character specifications
to scan and format big- and little-endian 16- and 32-bit integers,
machine- native single- and double-precision floating-point values,
and other formats. The binary command uses format
specifiers to determine what format data will be packed into, such as
S
to denote a 16-bit integer in big-endian[7] order. The format s denotes a 16-bit integer in
little-endian order. See the documentation for a complete list of
specifiers. Here is a sample use of
binary:
set binaryMsg [binary format SI 3 129];# 16 & 32-bit big endian ints
If you are scanning or formatting binary data for use by other
programs on the same machine type, consult the endian order
information in tcl_platform
to choose the correct
binary specification:
switch $tcl_platform(byteOrder) { littleEndian { set int32 i ; set int16 s } bigEndian { set int32 I ; set int16 S } } binary scan $binaryMsg $int16$int32 messageNum messageCode
Note that the binary command does not have a specification character to scan unsigned integers. Signed integers can be converted to unsigned quantities with a simple expression. Consult the binary command manpages for more information.
# convert to 16 bit unsigned value set messageNum [expr ($messageCode + 0x10000) % 0x10000]
[7] Endian refers to how a particular CPU actually stores integer values in memory. Big-endian processors store integers with the most significant bytes first; little-endian processors store integers with the least significant bytes first.