Programming Using Tcl/Tk Week 5
description
Transcript of Programming Using Tcl/Tk Week 5
Programming Using Tcl/TkWeek 5
Seree Chinodom
http://lecture.compsci.buu.ac.th/TclTk
First Things First Homework #2
– Some good work
Project: Hand them in, if you've got 'em
To have your project returned, send SASE to:
Ernest Friedman-HillErnest Friedman-Hill
1206 Caribou Place1206 Caribou Place
Davis, CA 95616Davis, CA 95616
Grading method choice– CLG: Credit, letter grade– CP/NP: Credit / No Credit (Pass / Fail)– NC: Not for credit
What We'll Do Today
Extending Tcl with C
A look at some third-party Tcl extensions I use– Expect– BLT– TclDii
The future of Tcl/Tk
Extending Tcl: Outline
Philosophy: focus on primitives.
Basics: interpreters, executing scripts.
Implementing new commands.
Managing packages; dynamic loading.
Managing the result string.
Useful library procedures: parsing, variables, lists, hash tables.
Philosophy Usually better to write Tcl scripts than C code:
– Faster development (higher level, no compilation).– More flexible.
Why write C?– Need access to low-level facilities (hardware).– Efficiency concerns (iterative calculations).– Need more structure (code is complex).
Implement new Tcl commands that provide a few simple orthogonal primitives:– Low-level to provide independent access to all key features.– High-level to hide unimportant details, allow efficient imple
mentation.
Example: Weather Reports Goal: retrieve weather reports over network from servers.
Tcl command set #1:– Retrieve report, format, print on
standard output.
Tcl command set #2:– Open socket to weather server.– Select station.– Retrieve first line of report....
Tcl command set #3:– Return list of available stations.– Given station name, retrieve report.
Too high-level (inflexible)
Too low-level (tedious)
Just right
Designing New Commands Choose textual names for objects:
.dlg.bottom.ok 3file or stdin
– Use hash tables to map to C structures. Object-oriented commands:
- .dlg.bottom.ok configure fg red– Good for small numbers of well-defined objects.– Doesn't pollute name space.– Allows similar commands for different objects.
Action-oriented commands: string compare $x $y
– Good if many objects or short-lived objects.
Designing New Commands, cont'd
Formatting command results:– Make them easy to parse with Tcl scripts:
tmp 53 hi 68 lo 37 precip .02 sky part– Make them symbolic wherever possible, e.g. not
53 68 37 .02 7
Use package prefixes in command names and global variables:
wthr_stationswthr_reportmidi_play
– Allows packages to coexist without name clashes.
Interpreters
Tcl_Interp structure encapsulates execution state:– Variables.– Commands implemented in C.– Tcl procedures.– Execution stack.
Can have many interpreters in a single application (but usually just one).
Creating and deleting interpreters: Tcl_Interp *interp;
interp = Tcl_CreateInterp();Tcl_DeleteInterp(interp);
Executing Tcl Scripts
int code; code = Tcl_Eval(interp, "set a 1"); code = Tcl_EvalFile(interp, "init.tcl"); code = Tcl_VarEval(interp, "set ", a, " 1");
code indicates success or failure:– TCL_OK: normal completion.– TCL_ERROR: error occurred.
-interp >result points to string: result or error message.
Application should display result or message for user.
Where Do Scripts Come From?
Read from standard input (see tclMain.c).
Read from script file (see tclMain.c).
Associate with X events, wait for events, invoke associated scripts (see tkMain.c).
Embeddded in C code (fixed or private scripts)
Creating New Tcl Commands Write command procedure in C:
int EqCmd(ClientData clientData, Tcl_Interp *interp, int argc, char **argv) { if (argc != 3) { ->>>>>>> > >>>>>> > >>>>>>#
return TCL_ERROR; } 1 2if (!strcmp(argv[ ], argv[ ])) - 1interp >result = " "; else - 0interp >result = " "; return TCL_OK;}
Creating New Tcl Commands, cont'd
Register with interpreter:Tcl_CreateCommand(interp, "eq", EqCmd, (ClientData) NULL, ...);
Once registered, EqCmd will be called whenever eq command is invoked in interp.
Command can be deleted laterTcl_DeleteCommand(interp, "eq");
–This is most useful for 'object' commands
ClientData Tcl_CreateCommand(interp, "eq", EqCmd,
clientData , ...); int EqCmd( ClientData clientData , ...) {...}
Used to pass any one-word value to command procedures and other callbacks.
clientData is usually a pointer to data structure manipulated by procedure.
Cast pointers in and out of ClientData type:– Tcl_CreateCommand(... (ClientData) gizmoPtr,
...);– gizmoPtr = (Gizmo *) clientData;
Lets many object commands share one command proc
Conventions For Packages
Goal: make it easy to develop and use Tcl extensions.
1. Use package prefixes to prevent name conflicts:
– Pick short prefix for package, e.g. rdb.
– Use in all global names: C procedure: Rdb_Open C variable: rdb_NumRecords Tcl command: rdb_query
– See Tcl book and Tcl/Tk Engineering Manual for more details.
Packages, cont'd
2. Create package initialization procedure:– Named after package: Rdb_Init.– Creates package's commands.– Evaluates startup script, if any.
int Rdb_Init(Tcl_Interp *interp) { Tcl_CreateCommand(...); Tcl_CreateCommand(...); ... return Tcl_EvalFile(interp, "/usr/local/lib/rdb/init.tcl");}
Packages, cont'd
3. To use package:
– Compile as shared library, e.g. on Solaris:
cc -K pic -c rdb.c
ld -G -z text rdb.o -o rdb.so
– Dynamically load into tclsh or wish:
load rdb.so Rdb
– Tcl will call Rdb_Init to initialize the package.
Note: this is new since the text was published; much nicer than old static mechanism!
-Kpic: position independent code. -G: produce a shared object. undefined symbols allowed. -z text: force library to be read-only
The load command Several forms
load filenameload filename packageNameload "" packageName
wherefilename is libXYZ.sopackageName is XYZ
You can use info sharedlibextensionto decide between .dll, .so, etc.
You can use info loadedto see what packages have been loaded
Packages, cont'd
You can also load packages statically:
Tcl_StaticPackage(Tcl_Interp interp,char * pkgName,Tcl_PkgInitProc *InitProc,Tcl_PkgInitProc *safeInitProc)
…thenload "" XYZ
Dynamic loading is to be preferred
Managing The Result String
Need conventions for -interp >result:– Permit results of any length.– Avoid malloc overheads if possible.– Avoid storage reclamation problems (leaks).– Keep as simple as possible.
Normal state of interpreter (e.g., whenever command procedure is invoked):
Default: command returns empty string.
result
""
freeProcinterp
Result String, cont'd
Option 1: (semi-) static result.- 0interp >result = " ";
Option 2: use pre-allocated space in interp.- sprintf(interp >result, "Value is %d", i);
result
""
freeProcinterp
result
"Value is 2"
freeProcinterp
"0"
~200 bytes
Result String, cont'd Option 3: allocate new space for result.
- 2000interp >result = malloc( );...- >>>>>>=;
Tcl will call freeProc (if not NULL) to dispose of result.
Mechanism supports storage allocators other than malloc/free (if they have the same signatures!)
result
""
freefreeProcinterp
Procedures For Managing Result
Option 4: use library procedures.
Tcl_SetResult(interp, string, ...);replaces old value
Tcl_AppendResult(interp, string, string, ... string, (char *) NULL);
extends old value
Tcl_AppendElement(interp, string);
extends old value, as a list
Tcl_ResetResult(interp);
clears old value
Utility Procedures: Parsing
Used by command procedures to parse arguments: int value, code;
code = Tcl_GetInt(interp, argv[1], &value);
Stores integer in value.
Returns TCL_OK or TCL_ERROR.
If parse error, returns TCL_ERROR and leaves message in -interp >result.
Parsing (cont'd)
Other procedures:Tcl_GetDouble Tcl_ExprDoubleTcl_GetBoolean Tcl_ExprBooleanTcl_ExprLong Tcl_ExprString
Tcl_GetBoolean accepts 'yes', 'false', 1, 0…
Expr- variations interpret argument as an expression
Utility Procedures: Variables
Read, write, and unset: *;
value = Tcl_GetVar(interp, "a", ...); Tcl_SetVar(interp, "a", "new", ...);
Tcl_UnsetVar(interp, "a", ...);
Set traces: Tcl_TraceVar(interp, "a",
TCL_TRACE_READS|TCL_TRACE_WRITES, , ) ;
traceProc will be called during each read or write of a:– Can monitor accesses.– Can override value read or written.
Other Utility Procedures Parsing, assembling proper lists:
Tcl_SplitList(...)Tcl_Merge(...)
Flexible hash tables:Tcl_InitHashTable(...)Tcl_CreateHashEntry(...)Tcl_FindHashEntry(...)Tcl_DeleteHashEntry(...)Tcl_DeleteHashTable(...)
–Like having Tcl associative arrays in C–Excellent way to store clientData records for 'object-oriented' command model
Other Utilities (cont'd)
Dynamic strings:Tcl_DStringInit(...)Tcl_DStringAppend(...)Tcl_DStringAppendElement(...)Tcl_DStringValue(...)Tcl_DStringFree(...)
– Dynamic strings grow efficiently without bounds– Like a good String class in C++– Used internally by Tcl for result management, etc
Extending Tcl Summary
Interfaces to C are simple: Tcl was designed to make this true.
Focus on primitives, use Tcl scripts to compose fancy features.
Writing a Widget for Tk
Good News: One widget can work on UNIX, Win32, Mac– Tk port uses port of Xlib to support graphics
Bad News: You still have to write to Xlib!
Xlib
Tk
Widgets Tk only uses Xlib, the lowest-level part of the
X libraries. It doesn't use Xt, Athena, Motif, etc. To draw, you have to
use Xlib, too.
Writing a Widget for Tk
Tk supplies utilities– 3D outline drawing– Font utilities– Event notification, timers, idle procs
You supply – Tcl commands– Initialization procedure– Configuration table– Event handlers– Deletion callbacks
Use object-oriented command paradigm– One Tcl command per widget class– One Tcl command per widget instance
Expect
Terrific for creating GUIs for interactive command-line apps
Terrific for reacting to prompts from command-line apps
Expect can– Automate tedious interactive processes– Glue GUI actions to simulated keyboard outputs– Reattach subprocess to keyboard
Works only on true POSIX (UNIX) systems– Uses pseudottys (ptys), a UNIX construct
Expect (cont'd)
Commands:spawn: like background exec, but opens two-way pipe spawn telnet herzberg 80expect: responds to patterns from pipe expect { "connection refused" exit "unknown host" complain DNS login: login_proc default interact
}interact: reconnect two-way pipe to console
BLT Several 'megawidgets'
blt_graph is most useful
Other commands:blt_htextblt_drag&dropblt_barchart blt_table
BLT Graph Widget
blt_graph .g -height 175 -width 200 -font \
"-*-times-medium-r-normal-*-*-80-*-*-*-*-*-*"
.g legend configure -font \
"-*-times-medium-r-normal-*-*-80-*-*-*-*-*-*" \
-anchor nw -position "@65,10" -relief ridge
.g yaxis configure -title ""
.g xaxis configure -title "Time (sec)"
.g element create "Series1" -xdata $x1 -ydata $y1 \
-linewidth 1 -fg red -bg blue -label "Velocity"
.g element create "Series2" -xdata $x2 -ydata $y2 \
-linewidth 1 -fg green -bg blue -label "Stroke"
TclDii Lets Tcl/Tk talks to CORBA objects
CORBA lets objects written in different languages communicate
Tk GUIs for remote objects are easy and powerful
TclDii test scripts faster and easier than C++ code
A Look Ahead
Tcl 7.5Tk 4.1
Tcl 7.6Tk 4.2
Tcl 7.6plugTk 4.2plug
Tcl 7.7Tk 4.3
Tcl 8.0Tk ?.?
Grid manager revisions foruse by SpecTcl.
Embedding, other features for Netscape plugin.
Native look and feelfor PC and Mac.
Bytecode compiler.
Tcl 7.5p1Tk 4.1p1
Tcl 7.6 and Tk 4.2
Major revision of gridder, needed for SpecTcl FCS.
C API change for channel drivers (eliminate Tcl_File usage).
No other changes except bug fixes.
Now in Beta, final release any day now.
Tcl 7.6plug and Tk 4.2plug
Features needed for Netscape plugin:– Application embedding:
frame .x.y -container 1toplevel .t -use [winfo id .x.y]wish -use 0x6800004
– Focus revision.– Safe-Tk, security models.
Already released in plugin binaries.
No source release until Tcl 7.7/Tk4.3.
Tcl 7.7 and Tk 4.3 Native widgets on PC and Mac. New menu mechanism:
– Menu bars implemented with menu widgets.– New -menu option for toplevel windows.– Tear-off menus are clones (consistency guaranteed).– Can use same menu in several places.– Hide tear-off entries?
New font mechanism: (nice for non-UNIX!)label .l -font {times 12 bold}font create title -family Helvetica \ -size 24 -weight bold
label .l2 -font titlefont configure title -size 36
Tcl 7.7 and Tk 4.3, cont'd
Virtual bindings, event generation:event add <<Paste>> <Control-v>bind Entry <<Paste>> {...}event generate .t ButtonPress \ -button 1 -x 47 -y 18
Standard dialogs. Portable file commands: rm, mv, mkdir, rmdir, ... Binary I/O support:
– Read/write blocks of data.– Insert/extract fields of blocks.– Copy between channels.
Tcl 7.7 and Tk 4.3, cont'd
Other possible additions:– Megawidgets.– Image revisions:
No dithering. Better memory usage. Channel support. ...
– More text improvements (smooth scrolling, etc.).
Schedule estimate:– First alpha release October-November 1996.– Final release Q2 1997.
Tcl 8.0
Byte-code compiler (see ftp.neosoft.com for 3rd-party attempts)
New object system for data representation.
New C APIs for command procedures, many other Tcl library procedures (old interfaces still supported, but slow).
Namespaces?
Tcl 8.0, cont'd Possible changes in semantics:
– More aggressive list syntax checking, conversion: lappend, lindex.
– Changes to error messages, errorInfo (line numbers?). Schedule estimate:
– First alpha release October 1996.– Final release Q2 1997?– Additional speedups in later releases.
Other Projects
SpecTcl and SpecJava. WebEdit, microscripting:
– Edit Web pages WYSIWYG with WebEdit.– Insert Tcl/Tk scripts at various places.– Scripts fire at interesting times:
Site configuration time. Page fetch (CGI). On client machine (via plugin).
Safe-Tcl:– Better Tk support, socket communication.– Develop interesting security policies.– Add authentication, MD5 (signatures).