Check-in Differences

Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Difference From d188ff37aea01d13 To 3a4277f112906ea0

2001-08-24
21:55
Revision through web from Working User <[email protected]> check-in: cf2a012f10 user: tclhttpd tags: trunk
21:18
Revision through web from New User <[email protected]> check-in: d188ff37ae user: tclhttpd tags: trunk
20:57
Revision through web from Test User <[email protected]> check-in: 9fcf250ae1 user: tclhttpd tags: trunk
2001-02-08
17:51
Recorded some maintainer volunteers. check-in: 0a9b18fb75 user: dgp tags: trunk
10:50
Created for Mats Bengtsson <[email protected]> check-in: 3a4277f112 user: fellowsd tags: trunk
2001-02-07
16:50
Syntax fix from [email protected] Thanks! check-in: a9878abb51 user: fellowsd tags: trunk

Deleted CVSROOT/checkoutlist.
1
2
3
4
5
6
7
8
9
10
11
12
13













-
-
-
-
-
-
-
-
-
-
-
-
-
# The "checkoutlist" file is used to support additional version controlled
# administrative files in $CVSROOT/CVSROOT, such as template files.
#
# The first entry on a line is a filename which will be checked out from
# the corresponding RCS file in the $CVSROOT/CVSROOT directory.
# The remainder of the line is an error message to use if the file cannot
# be checked out.
#
# File format:
#
#	[<whitespace>]<filename><whitespace><error message><end-of-line>
#
# comment lines begin with '#'
Deleted CVSROOT/commitinfo.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15















-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# The "commitinfo" file is used to control pre-commit checks.
# The filter on the right is invoked with the repository and a list 
# of files to check.  A non-zero exit of the filter program will 
# cause the commit to be aborted.
#
# The first entry on a line is a regular expression which is tested
# against the directory that the change is being committed to, relative
# to the $CVSROOT.  For the first match that is found, then the remainder
# of the line is the name of the filter to run.
#
# If the repository name does not match any of the regular expressions in this
# file, the "DEFAULT" line is used, if it is specified.
#
# If the name "ALL" appears as a regular expression it is always used
# in addition to the first matching regex or "DEFAULT".
Deleted CVSROOT/config.
1
2
3
4
5
6
7
8
9
10
11











-
-
-
-
-
-
-
-
-
-
-
# Set this to "no" if pserver shouldn't check system users/passwords
SystemAuth=no

# Set `PreservePermissions' to `yes' to save file status information
# in the repository.
#PreservePermissions=no

# Set `TopLevelAdmin' to `yes' to create a CVS directory at the top
# level of the new working directory when using the `cvs checkout'
# command.
#TopLevelAdmin=no
Deleted CVSROOT/cvswrappers.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23























-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# This file affects handling of files based on their names.
#
# The -t/-f options allow one to treat directories of files
# as a single file, or to transform a file in other ways on
# its way in and out of CVS.
#
# The -m option specifies whether CVS attempts to merge files.
#
# The -k option specifies keyword expansion (e.g. -kb for binary).
#
# Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers)
#
#  wildcard	[option value][option value]...
#
#  where option is one of
#  -f		from cvs filter		value: path to filter
#  -t		to cvs filter		value: path to filter
#  -m		update methodology	value: MERGE or COPY
#  -k		expansion mode		value: b, o, kkv, &c
#
#  and value is a single-quote delimited value.
# For example:
#*.gif -k 'b'
Deleted CVSROOT/editinfo.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21





















-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# The "editinfo" file is used to allow verification of logging
# information.  It works best when a template (as specified in the
# rcsinfo file) is provided for the logging procedure.  Given a
# template with locations for, a bug-id number, a list of people who
# reviewed the code before it can be checked in, and an external
# process to catalog the differences that were code reviewed, the
# following test can be applied to the code:
#
#   Making sure that the entered bug-id number is correct.
#   Validating that the code that was reviewed is indeed the code being
#       checked in (using the bug-id number or a seperate review
#       number to identify this particular code set.).
#
# If any of the above test failed, then the commit would be aborted.
#
# Actions such as mailing a copy of the report to each reviewer are
# better handled by an entry in the loginfo file.
#
# One thing that should be noted is the the ALL keyword is not
# supported.  There can be only one entry that matches a given
# repository.
Deleted CVSROOT/loginfo.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27



























-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# The "loginfo" file controls where "cvs commit" log information
# is sent.  The first entry on a line is a regular expression which must match
# the directory that the change is being made to, relative to the
# $CVSROOT.  If a match is found, then the remainder of the line is a filter
# program that should expect log information on its standard input.
#
# If the repository name does not match any of the regular expressions in this
# file, the "DEFAULT" line is used, if it is specified.
#
# If the name ALL appears as a regular expression it is always used
# in addition to the first matching regex or DEFAULT.
#
# You may specify a format string as part of the
# filter.  The string is composed of a `%' followed
# by a single format character, or followed by a set of format
# characters surrounded by `{' and `}' as separators.  The format
# characters are:
#
#   s = file name
#   V = old version number (pre-checkin)
#   v = new version number (post-checkin)
#
# For example:
#DEFAULT (echo ""; id; echo %s; date; cat) >> $CVSROOT/CVSROOT/commitlog
# or
#DEFAULT (echo ""; id; echo %{sVv}; date; cat) >> $CVSROOT/CVSROOT/commitlog
^tip (date; cat; (sleep 2; cd /usr/local/web/tip; /usr/bin/cvs -q update -d) &) >> $CVSROOT/CVSROOT/updatelog 2>&1
Deleted CVSROOT/modules.
1
2
3
4
5
6
7







-
-
-
-
-
-
-
modules      CVSROOT modules
admin        web/admin
doc.site     web/doc.site
devxchg.site web/devxchg.site
dxc_res.site web/dxc_res.site
site_look    web/site_look
tip          tip
Deleted CVSROOT/notify.
1
2
3
4
5
6
7
8
9
10
11
12












-
-
-
-
-
-
-
-
-
-
-
-
# The "notify" file controls where notifications from watches set by
# "cvs watch add" or "cvs edit" are sent.  The first entry on a line is
# a regular expression which is tested against the directory that the
# change is being made to, relative to the $CVSROOT.  If it matches,
# then the remainder of the line is a filter program that should contain
# one occurrence of %s for the user to notify, and information on its
# standard input.
#
# "ALL" or "DEFAULT" can be used in place of the regular expression.
#
# For example:
#ALL mail %s -s "CVS notification"
Deleted CVSROOT/rcsinfo.
1
2
3
4
5
6
7
8
9
10
11
12
13













-
-
-
-
-
-
-
-
-
-
-
-
-
# The "rcsinfo" file is used to control templates with which the editor
# is invoked on commit and import.
#
# The first entry on a line is a regular expression which is tested
# against the directory that the change is being made to, relative to the
# $CVSROOT.  For the first match that is found, then the remainder of the
# line is the name of the file that contains the template.
#
# If the repository name does not match any of the regular expressions in this
# file, the "DEFAULT" line is used, if it is specified.
#
# If the name "ALL" appears as a regular expression it is always used
# in addition to the first matching regex or "DEFAULT".
Deleted CVSROOT/taginfo.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20




















-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# The "taginfo" file is used to control pre-tag checks.
# The filter on the right is invoked with the following arguments:
#
# $1 -- tagname
# $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d
# $3 -- repository
# $4->  file revision [file revision ...]
#
# A non-zero exit of the filter program will cause the tag to be aborted.
#
# The first entry on a line is a regular expression which is tested
# against the directory that the change is being committed to, relative
# to the $CVSROOT.  For the first match that is found, then the remainder
# of the line is the name of the filter to run.
#
# If the repository name does not match any of the regular expressions in this
# file, the "DEFAULT" line is used, if it is specified.
#
# If the name "ALL" appears as a regular expression it is always used
# in addition to the first matching regex or "DEFAULT".
Deleted CVSROOT/verifymsg.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21





















-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
# The "verifymsg" file is used to allow verification of logging
# information.  It works best when a template (as specified in the
# rcsinfo file) is provided for the logging procedure.  Given a
# template with locations for, a bug-id number, a list of people who
# reviewed the code before it can be checked in, and an external
# process to catalog the differences that were code reviewed, the
# following test can be applied to the code:
#
#   Making sure that the entered bug-id number is correct.
#   Validating that the code that was reviewed is indeed the code being
#       checked in (using the bug-id number or a seperate review
#       number to identify this particular code set.).
#
# If any of the above test failed, then the commit would be aborted.
#
# Actions such as mailing a copy of the report to each reviewer are
# better handled by an entry in the loginfo file.
#
# One thing that should be noted is the the ALL keyword is not
# supported.  There can be only one entry that matches a given
# repository.
Deleted CVSROOT/writers.
Changes to tip/1.tip.
1
2
3

4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
1
2

3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19





20
21
22
23
24
25
26
27
28
29
30
31
32


-
+
















-
-
-
-
-













TIP:            1
Title:          TIP Index
Version:        $Revision: 1.4 $
Version:        $Revision: 1.3 $
Author:         TIP Editor <[email protected]>
State:          Active
Type:           Informational
Vote:           No voting
Created:        14-Sep-2000
Post-History:

~ Abstract

This TIP contains the index of all TIPs published over the lifetime of
the TCT. It will be continually and automatically updated.

~ Index

#index:

White backgrounds indicate that the TIP is still a draft, yellow
backgrounds highlight TIPs being voted on, and where a TIP has been
rejected, withdrawn or obsoleted its index entry has a dark grey
background.

~ Explanations and How To Submit New TIPs

See [2] for a description of the editorial process a TIP has to go
through and [3] for a description of their structure and the commands
used to write them. You submit a TIP to this archive by emailing it
(preferably in source form) to the TIP editor <[email protected]>
who will check it for following of the guidelines, style and general
relevance to Tcl/Tk before checking it into the CVS archive and notifying
the author, the rest of the Tcl Core Team, and the relevant newsgroups.

~ Copyright

This document has been placed in the public domain.
Deleted tip/10.patch.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300












































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
? tests/http.test__
? tests/httpold.test__
Index: doc/CrtChannel.3
===================================================================
RCS file: /cvsroot/tcl/tcl/doc/CrtChannel.3,v
retrieving revision 1.8
diff -u -r1.8 CrtChannel.3
--- doc/CrtChannel.3	2000/10/06 21:06:08	1.8
+++ doc/CrtChannel.3	2001/02/28 21:20:07
@@ -11,7 +11,7 @@
 .BS
 '\" Note:  do not modify the .SH NAME line immediately below!
 .SH NAME
-Tcl_CreateChannel, Tcl_GetChannelInstanceData, Tcl_GetChannelType, Tcl_GetChannelName, Tcl_GetChannelHandle, Tcl_GetChannelMode, Tcl_GetChannelBufferSize, Tcl_SetChannelBufferSize, Tcl_NotifyChannel, Tcl_BadChannelOption, Tcl_ChannelName, Tcl_ChannelVersion, Tcl_ChannelBlockModeProc, Tcl_ChannelCloseProc, Tcl_ChannelClose2Proc, Tcl_ChannelInputProc, Tcl_ChannelOutputProc, Tcl_ChannelSeekProc, Tcl_ChannelSetOptionProc, Tcl_ChannelGetOptionProc, Tcl_ChannelWatchProc, Tcl_ChannelGetHandleProc, Tcl_ChannelFlushProc, Tcl_ChannelHandlerProc, Tcl_IsChannelShared, Tcl_IsChannelRegistered, Tcl_CutChannel, Tcl_SpliceChannel, Tcl_IsChannelExisting, Tcl_ClearChannelHandlers \- procedures for creating and manipulating channels
+Tcl_CreateChannel, Tcl_GetChannelInstanceData, Tcl_GetChannelType, Tcl_GetChannelName, Tcl_GetChannelHandle, Tcl_GetChannelMode, Tcl_GetChannelBufferSize, Tcl_SetChannelBufferSize, Tcl_NotifyChannel, Tcl_BadChannelOption, Tcl_ChannelName, Tcl_ChannelVersion, Tcl_ChannelBlockModeProc, Tcl_ChannelCloseProc, Tcl_ChannelClose2Proc, Tcl_ChannelInputProc, Tcl_ChannelOutputProc, Tcl_ChannelSeekProc, Tcl_ChannelSetOptionProc, Tcl_ChannelGetOptionProc, Tcl_ChannelWatchProc, Tcl_ChannelGetHandleProc, Tcl_ChannelFlushProc, Tcl_ChannelHandlerProc, Tcl_IsChannelShared, Tcl_IsChannelRegistered, Tcl_CutChannel, Tcl_SpliceChannel, Tcl_IsChannelExisting, Tcl_ClearChannelHandlers, Tcl_GetChannelThread \- procedures for creating and manipulating channels
 .SH SYNOPSIS
 .nf
 \fB#include <tcl.h>\fR
@@ -31,6 +31,11 @@
 int
 \fBTcl_GetChannelHandle\fR(\fIchannel, direction, handlePtr\fR)
 .sp
+.VS 8.4
+Tcl_ThreadId
+\fBTcl_GetChannelThread\fR(\fIchannel\fR)
+.VE
+.sp
 int
 \fBTcl_GetChannelBufferSize\fR(\fIchannel\fR)
 .sp
@@ -215,6 +220,12 @@
 then \fBTCL_ERROR\fR is returned instead.  Different channel drivers
 will return different types of handle.  Refer to the manual entries
 for each driver to determine what type of handle is returned.
+.VS 8.4
+.PP
+\fBTcl_GetChannelThread\fR returns the id of the thread currently managing
+the specified \fIchannel\fR. This allows channel drivers to send their file
+events to the correct event queue even for a multi-threaded core.
+.VE
 .PP
 \fBTcl_GetChannelMode\fR returns an OR-ed combination of \fBTCL_READABLE\fR
 and \fBTCL_WRITABLE\fR, indicating whether the channel is open for input
Index: generic/tcl.decls
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tcl.decls,v
retrieving revision 1.43
diff -u -r1.43 tcl.decls
--- generic/tcl.decls	2001/01/18 19:09:55	1.43
+++ generic/tcl.decls	2001/02/28 21:20:10
@@ -1501,6 +1501,9 @@
 declare 432 generic {
     int Tcl_AttemptSetObjLength(Tcl_Obj *objPtr, int length)
 }
+declare 433 generic {
+    Tcl_ThreadId Tcl_GetChannelThread(Tcl_Channel channel)
+}
 
 ##############################################################################
 
Index: generic/tclDecls.h
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclDecls.h,v
retrieving revision 1.44
diff -u -r1.44 tclDecls.h
--- generic/tclDecls.h	2001/01/18 19:09:55	1.44
+++ generic/tclDecls.h	2001/02/28 21:20:17
@@ -1350,6 +1350,9 @@
 /* 432 */
 EXTERN int		Tcl_AttemptSetObjLength _ANSI_ARGS_((
 				Tcl_Obj * objPtr, int length));
+/* 433 */
+EXTERN Tcl_ThreadId	Tcl_GetChannelThread _ANSI_ARGS_((
+				Tcl_Channel channel));
 
 typedef struct TclStubHooks {
     struct TclPlatStubs *tclPlatStubs;
@@ -1850,6 +1853,7 @@
     char * (*tcl_AttemptRealloc) _ANSI_ARGS_((char * ptr, unsigned int size)); /* 430 */
     char * (*tcl_AttemptDbCkrealloc) _ANSI_ARGS_((char * ptr, unsigned int size, char * file, int line)); /* 431 */
     int (*tcl_AttemptSetObjLength) _ANSI_ARGS_((Tcl_Obj * objPtr, int length)); /* 432 */
+    Tcl_ThreadId (*tcl_GetChannelThread) _ANSI_ARGS_((Tcl_Channel channel)); /* 433 */
 } TclStubs;
 
 #ifdef __cplusplus
@@ -3629,6 +3633,10 @@
 #ifndef Tcl_AttemptSetObjLength
 #define Tcl_AttemptSetObjLength \
 	(tclStubsPtr->tcl_AttemptSetObjLength) /* 432 */
+#endif
+#ifndef Tcl_GetChannelThread
+#define Tcl_GetChannelThread \
+	(tclStubsPtr->tcl_GetChannelThread) /* 433 */
 #endif
 
 #endif /* defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS) */
Index: generic/tclIO.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclIO.c,v
retrieving revision 1.28
diff -u -r1.28 tclIO.c
--- generic/tclIO.c	2001/01/30 17:32:06	1.28
+++ generic/tclIO.c	2001/02/28 21:20:34
@@ -1056,6 +1056,14 @@
     tsdPtr->firstCSPtr	= statePtr;
 
     /*
+     * TIP #10. Mark the current thread as the one managing the new
+     *          channel. Note: 'Tcl_GetCurrentThread' returns sensible
+     *          values even for a non-threaded core.
+     */
+
+    statePtr->managingThread = Tcl_GetCurrentThread ();
+
+    /*
      * Install this channel in the first empty standard channel slot, if
      * the channel was previously closed explicitly.
      */
@@ -1471,6 +1479,32 @@
 /*
  *----------------------------------------------------------------------
  *
+ * Tcl_GetChannelThread --
+ *
+ *	Given a channel structure, returns the thread managing it.
+ *	TIP #10
+ *
+ * Results:
+ *	Returns the id of the thread managing the channel.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_ThreadId
+Tcl_GetChannelThread(chan)
+    Tcl_Channel chan;		/* The channel to return managing thread for. */
+{
+    Channel *chanPtr = (Channel *) chan;	/* The actual channel. */
+
+    return chanPtr->state->managingThread;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
  * Tcl_GetChannelType --
  *
  *	Given a channel structure, returns the channel type structure.
@@ -2254,6 +2288,14 @@
 
     statePtr->nextCSPtr	= tsdPtr->firstCSPtr;
     tsdPtr->firstCSPtr	= statePtr;
+
+    /*
+     * TIP #10. Mark the current thread as the new one managing this
+     *          channel. Note: 'Tcl_GetCurrentThread' returns sensible
+     *          values even for a non-threaded core.
+     */
+
+    statePtr->managingThread = Tcl_GetCurrentThread ();
 }
 
 /*
Index: generic/tclIO.h
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclIO.h,v
retrieving revision 1.2
diff -u -r1.2 tclIO.h
--- generic/tclIO.h	2000/09/28 06:38:21	1.2
+++ generic/tclIO.h	2001/02/28 21:20:37
@@ -233,6 +233,8 @@
 				 * long as the channel state. Never NULL. */
     struct ChannelState *nextCSPtr;
 				/* Next in list of channels currently open. */
+    Tcl_ThreadId managingThread; /* TIP #10: Id of the thread managing
+				  * this stack of channels. */
 } ChannelState;
     
 /*
Index: generic/tclStubInit.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclStubInit.c,v
retrieving revision 1.47
diff -u -r1.47 tclStubInit.c
--- generic/tclStubInit.c	2001/01/18 19:09:55	1.47
+++ generic/tclStubInit.c	2001/02/28 21:20:39
@@ -836,6 +836,7 @@
     Tcl_AttemptRealloc, /* 430 */
     Tcl_AttemptDbCkrealloc, /* 431 */
     Tcl_AttemptSetObjLength, /* 432 */
+    Tcl_GetChannelThread, /* 433 */
 };
 
 /* !END!: Do not edit above this line. */
Index: generic/tclTest.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclTest.c,v
retrieving revision 1.22
diff -u -r1.22 tclTest.c
--- generic/tclTest.c	2000/11/24 11:27:37	1.22
+++ generic/tclTest.c	2001/02/28 21:20:47
@@ -4517,6 +4517,18 @@
         return TCL_OK;
     }
     
+    if ((cmdName[0] == 'm') && (strncmp(cmdName, "mthread", len) == 0)) {
+        if (argc != 3) {
+            Tcl_AppendResult(interp, "channel name required",
+                    (char *) NULL);
+            return TCL_ERROR;
+        }
+
+        TclFormatInt(buf, Tcl_GetChannelThread (chan));
+        Tcl_AppendResult(interp, buf, (char *) NULL);
+        return TCL_OK;
+    }
+
     if ((cmdName[0] == 'n') && (strncmp(cmdName, "name", len) == 0)) {
         if (argc != 3) {
             Tcl_AppendResult(interp, "channel name required",
Index: tests/io.test
===================================================================
RCS file: /cvsroot/tcl/tcl/tests/io.test,v
retrieving revision 1.14
diff -u -r1.14 io.test
--- tests/io.test	2000/04/10 17:19:00	1.14
+++ tests/io.test	2001/02/28 21:20:55
@@ -6722,6 +6722,29 @@
     list $x $result
 } {1 {gets {normal message from pipe} gets {} catch {error message from pipe}}}
 
+
+
+if {[info commands testthread] != {}} {
+    set mainthread [testthread id]
+} else {
+    set mainthread 0
+}
+
+test io-59.1 {Thread reference of channels} {
+    # TIP #10
+    # More complicated tests (like that the reference changes as a
+    # channel is moved from thread to thread) can be done only in the
+    # extension which fully implements the moving of channels between
+    # threads, i.e. 'Threads'. Or we have to extend [testthread] as well.
+
+    set f [open longfile r]
+    set result [testchannel mthread $f]
+    close $f
+    set result
+} $mainthread
+
+
+
 # cleanup
 foreach file [list fooBar longfile script output test1 pipe my_script foo \
 	bar test2 test3 cat stdout] {
@@ -6730,16 +6753,3 @@
 ::tcltest::restoreState
 ::tcltest::cleanupTests
 return
-
-
-
-
-
-
-
-
-
-
-
-
-
Index: unix/mkLinks
===================================================================
RCS file: /cvsroot/tcl/tcl/unix/mkLinks,v
retrieving revision 1.18
diff -u -r1.18 mkLinks
--- unix/mkLinks	2001/01/18 19:09:56	1.18
+++ unix/mkLinks	2001/02/28 21:20:57
@@ -165,6 +165,7 @@
     rm -f Tcl_SpliceChannel.3
     rm -f Tcl_IsChannelExisting.3
     rm -f Tcl_ClearChannelHandlers.3
+    rm -f Tcl_GetChannelThread.3
     ln CrtChannel.3 Tcl_CreateChannel.3
     ln CrtChannel.3 Tcl_GetChannelInstanceData.3
     ln CrtChannel.3 Tcl_GetChannelType.3
@@ -195,6 +196,7 @@
     ln CrtChannel.3 Tcl_SpliceChannel.3
     ln CrtChannel.3 Tcl_IsChannelExisting.3
     ln CrtChannel.3 Tcl_ClearChannelHandlers.3
+    ln CrtChannel.3 Tcl_GetChannelThread.3
 fi
 if test -r CrtChnlHdlr.3; then
     rm -f Tcl_CreateChannelHandler.3
Changes to tip/10.tip.
1
2
3

4
5

6
7

8
9
10
11
12
13
14
1
2

3
4

5
6

7
8
9
10
11
12
13
14


-
+

-
+

-
+







TIP:            10
Title:          Tcl I/O Enhancement: Thread-Aware Channels
Version:        $Revision: 1.6 $
Version:        $Revision: 1.3 $
Author:         Andreas Kupries <[email protected]>
State:          Final
State:          Draft
Type:           Project
Vote:           Done
Vote:           Pending
Created:        08-Nov-2000
Post-History:   
Tcl-Version:    8.4

~ Abstract

This TIP describes how to change the generic I/O layer in the Tcl core
94
95
96
97
98
99
100
101
102
103




104
105
106
107
94
95
96
97
98
99
100



101
102
103
104
105
106
107
108







-
-
-
+
+
+
+




   1. Declare a new API function to retrieve the Id of the managing
      thread from a channel. Add this declaration to generic/tcl.decls
      and implement the function in the file generic/tclIO.c.  I
      propose ''Tcl_GetChannelThread'' as the name of this new API
      function.

A patch implementing all of the changes described above and
additionally extending the documentation and the test-suite
is available here:
http://www.cs.man.ac.uk/fellowsd-bin/TIP/10.patch
additionally extending the documentation and the testsuite
was registered at SourceForge. The Id is 103538. A direct
reference is available:
http://sourceforge.net/patch/?func=detailpatch&patch_id=103538&group_id=10894

~ Copyright

This document has been placed in the public domain.
Changes to tip/10000.tip.
1
2
3

4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
1
2

3
4
5
6
7
8
9
10




11
12
13
14
15
16
17


-
+







-
-
-
-







TIP:            10000
Title:          Dummy Proposal for Testing Editing Interfaces
Version:        $Revision: 1.85 $
Version:        $Revision: 1.49 $
Author:         Don Porter <[email protected]>
Author:         <[email protected]>
Author:         Andreas Kupries <[email protected]>
Author:         Donal K. Fellows <[email protected]>
Author:         Andreas Kupries <[email protected]>
Author:         <[email protected]>
Author:         Richard Suchenwirth <[email protected]>
Author:         Kevin B KENNY <[email protected]>
Author:         Jeff Hobbs <[email protected]>
Author:         Test User <[email protected]>
Author:         New User <[email protected]>
State:          Draft
Type:           Informative
Vote:           Pending
Created:        03-Dec-2000
Post-History:   

~ Abstract
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71







72
73
74
75
76
77
78
25
26
27
28
29
30
31























32
33
34
35
36
37
38
39
40
41
42
43

44
45
46
47
48
49
50
51
52
53
54
55
56
57







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-












-
+
+
+
+
+
+
+







This document serves a purpose similar to the Graffiti page
(http://purl.org/thecliff/tcl/wiki/34.html) at the Tcl'ers
Wiki (http://purl.org/thecliff/tcl/wiki/).

It will also be useful for testing the web editing interface
proposed in [13].

~ ActiveState Server Test

Testing after Tcl upgrade... Do I see these changes?

How about these changes?

Quick check after TIP software update.

Things still working after the move?  Looking good.

Checking cron update at scriptics.com.

~ New Features Test

Gotta try the log message...
...and the cookies...
Hmmm... no cookies!
Donal says it's better now...
...but I still don't see any fields filled in for me...
...but now I do!

''still trying to get the cookies working - DKF''

~ Submission Test

Some browsers are spinning their wheels after submission...
Looks like this is fixed now.

~ Author Add Test

Checking fix for missing Abstract after adding a new Author...
Fixed.

~ Reload/caching Test

See if additional HTTP headers help... Yes.  More from Jeff.
See if additional HTTP headers help... Yes.

~ Test

Attempt to add a new section via the web interface (in a frame).

Are anonymous changes possible?

~ Testing the interface

<Andreas Kupries>
Just my first try at the new web editing interface for TIPs.

Hm ... Maybe we could add a direct reference to [3] to the
92
93
94
95
96
97
98

99
100





101
102



103
104



105


106
107
108
109
71
72
73
74
75
76
77
78


79
80
81
82
83


84
85
86


87
88
89

90
91
92
93
94
95







+
-
-
+
+
+
+
+
-
-
+
+
+
-
-
+
+
+
-
+
+




That's it for now. ... I'll add the same comments to [13], they belong
there more than here.
</Andreas Kupries>

<note by="Richard Suchenwirth" date="2001-01-30">Whitespace in XML element names won't work.. or is 
"Kupries" an attribute without value?</note>

~ ChangeLog
~ Dummy <Section> 'To' "Test" XML Generation


| $Log: not supported by cvs2svn $
| Revision 1.48  2001/01/30 09:40:49  tclhttpd
| Revision through web from Richard GH Suchenwirth <[email protected]> (15856)
|
Move along now; nothing to see here...

| Revision 1.47  2001/01/26 22:36:21  tclhttpd
| Revision through web from  <[email protected]> (6062)
|
~ TIPs as PostScript and Adobe PDF

| Revision 1.46  2001/01/26 22:35:19  tclhttpd
| Revision through web from  <[email protected]> (6043)
| 
http://www.cs.man.ac.uk/~fellowsd/tcl/bitsandpieces/tips_on_20010622.pdf
| Revision 1.45  2001/01/26 22:34:27  tclhttpd
| Revision through web from  <[email protected]> (6023)

~ Copyright

This document has been placed in the public domain.
Changes to tip/11.tip.
1
2
3

4
5

6
7
8
9
10
11
12
1
2

3
4

5
6
7
8
9
10
11
12


-
+

-
+







TIP:            11
Title:          Tk Menubutton Enhancement: -compound option for menubutton
Version:        $Revision: 1.5 $
Version:        $Revision: 1.4 $
Author:         Todd Helfter <[email protected]>
State:          Final
State:          Accepted
Type:           Project
Tcl-Version:    8.4
Vote:           Done
Created:        16-Nov-2000
Post-History:

~ Abstract
Changes to tip/12.tip.
1
2
3

4
5
6
7

8
9
10
11

12
13
14
15
16
17
18
1
2

3
4

5

6
7
8

9
10
11
12
13
14
15
16
17


-
+

-

-
+


-

+







TIP:            12
Title:          The "Batteries Included" Distribution
Version:        $Revision: 1.3 $
Version:        $Revision: 1.2 $
Author:         George A. Howlett <[email protected]>
Author:         Larry W. Virden <[email protected]>
State:          Draft
Type:           Informative
Type:           Informational
Vote:           Pending
Created:        15-Sep-2000
Post-History:   
Discussions-To: news:comp.lang.tcl
Post-History: 

~ Abstract

This document describes a comprehensive Tcl/Tk distribution.  Its
primary purpose is to create a standard source tree that includes Tcl,
Tk, and extensions so that they can be built and installed in an
simple and easy manner.
67
68
69
70
71
72
73
74
75


76
77
78
79
80
81
82
83
84
85
86
87
88
89

90
91
92
93
94
95
96
97

98
99
100
101
102
103
104
105
106
107
108
109
110
111

112
113
114
115
116

117
118
119
120
121
122
123
66
67
68
69
70
71
72


73
74
75
76
77
78
79
80
81
82
83
84
85
86
87

88
89
90
91
92
93
94
95

96
97
98
99
100
101
102
103
104
105
106
107
108
109

110
111
112
113
114

115
116
117
118
119
120
121
122







-
-
+
+













-
+







-
+













-
+




-
+







relationship between Tcl and its parts.  After all, application
writers first care about whether a feature or capability is available,
not how it's structured under the hood.

~ The "Batteries Included" Distribution.

Let's start with a very modest example.  Let's imagine that the
"Batteries Included" distribution is nothing more than an archive file of
the source code for Tcl/Tk and several extensions.
"Batteries Included" distribution is nothing more than a tar file of
Tcl/Tk and several extensions.

|            Unix    Windows  Mac
|             ----    -------  ---
|  Tcl 8.3       x       x      x
|  Tk 8.3        x       x      x
|  [incr Tcl]    x       x      x
|  expect        x       ?
|  TclX          x
|  BLT           x       x
|  Trf           
|  Html widget
|  XML
|  ...lots more...

  
Tcl, Tk, and the packages are configured such that they can be built
and installed just from a top level directory (not individually).
Someone can download and try out all sorts of new features without
repeating the same "configure", "make", "make install" sequences.

With this simple tar file, the following benefits are automatically
generated:

  
  * It provides a simple way for users to try out extensions.  Users
    only have to run download, configure, compile and install, at
    most, once.

  * It describes a clear framework for extensions.  We will have
    established a directory structure for both source code and
    installed binaries.  It will be much more clear how to
    inter-operate.  This is TEA in action.

  * It's better for Tcl/Tk application writers.  You can count on
    features being universally available.  Your program can again be
    just a Tcl script, not an array of packages that everyone needs to
    download and install.

     
  * It's better for extension writers.  Configuration is simpler,
    since you know where all the sources and the compiler-specific
    information will reside.  You don't need to search for
    ''tclConfig.sh'' or ''tkConfig.sh'' files.

     
  * It's better for Tcl/Tk distribution builders.  This includes both
    the Linux distributors and company sysadmins that build Tcl/Tk.
    They don't have to fear installing extensions because of version
    dependencies.

  > Let's give Redhat and SuSE a good reason to move off of version
    8.0. One the big advantages of Linux over (let's say) Solaris is
185
186
187
188
189
190
191
192

193
194
195
196
197
198
199
200
201
202
203
204

205
206
207
208
209
210
211
184
185
186
187
188
189
190

191

192
193
194
195
196
197
198
199
200
201

202
203
204
205
206
207
208
209







-
+
-










-
+








 * Identify extensions.  

 > What extensions should be included in the near term?  We need
   extension authors that are willing to work with us to build a
   directory framework, change configuration files, etc.  Extensions
   do not need to work on all platforms.  For example, there is a
   wealth of Windows-based extensions that should be included in 
   wealth of Windows-based extensions that should be included.
   a Windows specific build.

 > What are the minimum requirements for extensions in the short term?
   Manual pages, html, tests, demos all would be nice.  We need to
   temper this with what's practical.  This is a learning process. We
   can adjust requirements in future phases.

 * Determine build and install directory structures.  

 > We need to make this work with more that one release installed.
   Don't suppose that there only one version will ever be used.

   
 * Setup CVS archives.

 * Create configuration files.  

 > This will require negotiation with extension writers.  We want
   their buy-in so they will maintain the changes.

265
266
267
268
269
270
271
272

273
274
275
276
277
278
279
280
281

282
283
284
285
286
287
288
289
290
291
292
293
294
263
264
265
266
267
268
269

270
271
272
273
274
275
276
277
278

279
280
281
282
283
284
285
286
287
288
289
290
291
292







-
+








-
+














The last phases are sketchy.  Feel free to add to this list, further
breaking down goals into subtasks.

~ Open Issues

 * Windows and MacIntosh sources.

 
 > Given the dearth of configuration tools for these platforms, it's
   likely that only binary installations will be available for the
   near term.

 * Documentation

 > Overlap in command and widget names can be neatly handled by
   namespaces.  Need to consider how to handle manual pages.

 
~ More Information

If anyone has interest to participate or would like to add comments to
the "Batteries Included" proposal, please send mail to George Howlett
<[email protected]>.

~ Copyright

This document has been placed in the public domain.

~ See Also

[4] by Brent Welch <[email protected]>.
Changes to tip/13.tip.
1
2
3

4
5
6
7
8
9
10
1
2

3
4
5
6
7
8
9
10


-
+







TIP:            13
Title:          Web Service for Drafting and Archiving TIPs
Version:        $Revision: 1.25 $
Version:        $Revision: 1.22 $
Author:         Don Porter <[email protected]>
Author:         Donal K. Fellows <[email protected]>
State:          Accepted
Type:           Process
Vote:           Done
Created:        21-Nov-2000
Post-History:   
132
133
134
135
136
137
138
139

140
141
142
143
144
145
146
132
133
134
135
136
137
138

139
140
141
142
143
144
145
146







-
+








The modifications to the Fellows TIP rendering engine that add the
capabilities proposed above are now merged in.  The TIP rendering
engine is maintained at
http://sourceforge.net/projects/tiprender/ .  To enable the
web-editing features, set the Tcl variable FEATURE(EDIT) to 1 in
the file config.tcl.  A working version of the proposed web service
is available at http://purl.org/tcl/home/cgi-bin/tct/tip/ .
is available at http://www.scriptics.com:8080/cgi-bin/tct/tip/ .

For what it's worth, this TIP was created primarily within a web
browser, making revisions through the web interface provided by the
reference implementation.

One remaining shortcoming of the reference implementation is that it
provides no mechanism for uploading images to the TIP repository.
234
235
236
237
238
239
240
241
242
243



244
245
246
247
248
249
250
251
234
235
236
237
238
239
240



241
242
243
244
245
246
247
248
249
250
251







-
-
-
+
+
+








 * ''I had the server time out on me''

 > That's troubling.  Can anyone seeing this problem provide any more
   information.  What were the circumstances, in detail?

 * ''Add links to an interface showing revision history''

 > Check out the [History] links at the bottom of the HTML rendered pages.
   Thanks to Donal Fellows for coding that up.  (OK, so we *did* reinvent
   CVSWeb.)
 > Once we have CVSweb installed and operating on the same server, that
   will be done.  With the TIPs already in CVS, that should not be
   difficult.  We should not re-invent CVSweb.

 * ''A separate <TEXTAREA> for the Abstract''

 > This is now implemented.  Please give it a try.

~ Copyright

This document has been placed in the public domain.
Changes to tip/14.tip.
1
2
3

4
5
6
7
8

9
10
11
12
13
14
15
1
2

3
4
5
6
7

8
9
10
11
12
13
14
15


-
+




-
+







TIP:            14
Title:          Access (via tkInt) to Tk Photo Image Transparency
Version:        $Revision: 1.3 $
Version:        $Revision: 1.2 $
Author:         Donal K. Fellows <[email protected]>
State:          Draft
Type:           Project
Tcl-Version:	8.4.0
Vote:           Pending
Vote:           In progress
Created:        22-Nov-2000
Keywords:	Tk, photo, transparency, internal, access
Post-History:   

~ Abstract

It is useful for some extensions to have access to the transparency
Changes to tip/15.tip.
1
2
3

4
5

6

7

8

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

57
58

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

80
81
82
83
84
85
86
87
88
89
90

91
92
93
94
95
96
97
98
99
1
2

3
4

5
6
7

8
9
10
11


12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

32










33
34
35
36
37
38
39
40
41
42
43
44
45

46
47

48
49
50
51
52





53
54
55
56
57
58
59
60
61
62
63

64
65
66
67
68
69
70
71
72
73


74





75
76
77
78


-
+

-
+

+
-
+

+

-
-




















-
+
-
-
-
-
-
-
-
-
-
-













-
+

-
+




-
-
-
-
-











-
+









-
-
+
-
-
-
-
-




TIP:            15
Title:          Functions to List and Detail Math Functions
Version:        $Revision: 1.8 $
Version:        $Revision: 1.1 $
Author:         Donal K. Fellows <[email protected]>
State:          Final
State:          Draft
Type:           Project
Tcl-Version:	8.4.0
Vote:           Done
Vote:           Pending
Created:        22-Nov-2000
Keywords:	Tcl, expr, function, introspection
Post-History:   
Keywords:       Tcl,expr,function,introspection
Tcl-Version:    8.4.0

~ Abstract

Provides a way for the list of all math functions defined in the
current interpreter to be discovered, and for discovering what
arguments might be passed to an existing math function.  This may be
useful in tests as well as more general use.

~ Rationale

Although it is quite easy to define a new function for use in
expressions, there is no public way of performing introspection on
this information.  Having a way to extract the arguments from an
existing math function was requested by
http://sourceforge.net/bugs/?func=detailbug&bug_id=119304&group_id=10894
and once you have one, it becomes trivial to also ask for a second
function to list what functions are defined.

I propose the creation of two functions that fulfil this r�le;
''Tcl_GetMathFuncInfo'' and ''Tcl_ListMathFuncs''.  These functions
will be documented on the same manual page as ''Tcl_CreateMathFunc''
will be documented on the same manual page as ''Tcl_CreateMathFunc''.
and implemented in the same file.

Furthermore, I also propose that the ''info'' command in the Tcl
interpreter be extended to include a new subcommand, ''functions'',
which will allow Tcl scripts to discover the list of installed
functions (by acting as a thin veneer over ''Tcl_ListMathFuncs''.)
Note that this is an extension of the ''info'' command because it
allows for introspection of a system that affects the behaviour of
several commands that form the core part of the command-set: ''expr'',
''for'', ''if'' and ''while''.

~ Tcl_GetMathFuncInfo

This function will take an interpreter reference, a function name (as
a string) and pointers to variables capable of taking each of the last
four arguments to ''Tcl_CreateMathFunc'', and will return a standard
Tcl result (either ''TCL_OK'' or ''TCL_ERROR'', depending on whether a
function with the given name exists within the given interpreter, with
an error message being left in the interpreter's result in the
''TCL_ERROR'' case.)  The array of argument types whose reference is
placed into the variable pointed to by ''argTypesPtr'' will be
allocated by Tcl, and should be freed with ''Tcl_Free''.

|int Tcl_GetMathFuncInfo(Tcl_Interp *interp, CONST char *name,
|int Tcl_GetMathFuncInfo(Tcl_Interp *interp, char *name,
|                        int *numArgsPtr, Tcl_ValueType **argTypesPtr,
|                        Tcl_MathProc **procPtr,
|                        Tcl_MathProc *procPtr,
|                        ClientData *clientDataPtr);

The parameter names are chosen by analogy with ''Tcl_CreateMathFunc''.

In the case where a math function is defined internally by the bytecode
engine and has no standard implementation (all the builtin functions in
8.4a2 are like this) the value placed in the variable indicated by the
''procPtr'' argument will be NULL.

~ Tcl_ListMathFuncs

This function will take an interpreter reference and an optional
string that describes a glob-like pattern that restricts the set of
math functions that the caller is interested in receiving (with a
''NULL'' indicating that no filtering is desired.)  The function will
return a pointer to a newly-allocated ''Tcl_Obj'' list of the names of
all the math functions defined within that interpreter, or ''NULL'' in
the case of an error (in which case a suitable message will be left in
the interpreter.)  The list will not be required to be sorted.

|Tcl_Obj *Tcl_ListMathFuncs(Tcl_Interp *interp, CONST char *pattern);
|Tcl_Obj *Tcl_ListMathFuncs(Tcl_Interp *interp, char *pattern);

The alternative is to pass in the addresses of variables that will be
updated to contain the number of functions and an array of function
names.  But I prefer the ''Tcl_Obj'' approach as it is expressing the
fact that the list of function names is really a single thing being
returned (albeit one that is not a simple value.)  It is not
anticipated that the performance of this function will need to be
crucial to too many applications.

~ info functions

Maybe this should be mapped to an ''info'' subcommand.
This new subcommand will provide access from Tcl scripts to the
functionality of ''Tcl_ListMathFuncs''.  It will take a single optional
argument consisting of a pattern to pass on as the ''pattern'' argument
(with the absence of the argument indicating that NULL is to be passed
instead.)

~ Copyright

This document is placed in the public domain.
Changes to tip/16.tip.
1
2
3

4
5
6
7
8
9
10
1
2

3
4
5
6
7
8
9
10


-
+







TIP:            16
Title:          Tcl Functional Areas for Maintainer Assignments
Version:        $Revision: 1.10 $
Version:        $Revision: 1.7 $
Author:         Don Porter <[email protected]>
State:          Accepted
Type:           Process
Vote:           Done
Created:        21-Nov-2000
Post-History:   

122
123
124
125
126
127
128
129

130
131
132
133
134
135
136
137
138
139
140


141
142
143
144
145
146

147
148
149
150
151
152
153
154
155
156
157
158
159
160

161
162
163
164
165
166
167
168
122
123
124
125
126
127
128

129

130
131
132
133
134
135
136
137
138

139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160

161

162
163
164
165
166
167
168







-
+
-









-
+
+






+













-
+
-







     generic/tclVar.c,
     tests/append.test,
     tests/set.test,
     tests/set-old.test,
     tests/upvar.test,
     tests/var.test

   >   1. ''Environment Variables'' - doc/Environment.3,
   >   1. ''Environment Variables'' - generic/tclEnv.c,
     generic/tclEnv.c,
     mac/tclMacEnv.c,
     tests/env.test

   >   1. ''Linked C Variables'' - doc/LinkVar.3,
     generic/tclLink.c,
     tests/link.test

   Objects: 

   >   1. ''Object System and Fundamental Object Types'' - doc/Backslash.3,
   >   1. ''Object System and Fundamental Object Types'' - doc/Access.3,
     doc/Backslash.3,
     doc/BoolObj.3,
     doc/Concat.3,
     doc/DoubleObj.3,
     doc/DString.3,
     doc/Encoding.3,
     doc/FindExec.3,
     doc/GetCwd.3,
     doc/Hash.3,
     doc/IntObj.3,
     doc/Object.3,
     doc/ObjectType.3,
     doc/PrintDbl.3,
     doc/SplitList.3,
     doc/StringObj.3,
     doc/StrMatch.3,
     generic/tclEncoding.c,
     generic/tclHash.c,
     generic/tclObj.c,
     generic/tclStringObj.c,
     generic/tclUtil.c,
     library/encoding/*.enc,
     library/encoding/*.enc
     tools/encoding/*,
     tests/dstring.test,
     tests/encoding.test,
     tests/stringObj.test,
     tests/obj.test,
     tests/util.test

   >   1. ''Conversions From String'' - doc/GetInt.3,
315
316
317
318
319
320
321

322
323

324

325



326
327
328
329
330
331
332
315
316
317
318
319
320
321
322
323
324
325
326
327

328
329
330
331
332
333
334
335
336
337







+


+

+
-
+
+
+







     doc/ChnlStack.3,
     doc/CrtChnlHdlr.3,
     doc/CrtCloseHdlr.3,
     doc/CrtChannel.3,
     doc/DetachPids.3,
     doc/GetStdChan.3,
     doc/OpenFileChnl.3,
     doc/SetErrno.3,
     generic/tclIO.c,
     generic/tclIO.h,
     generic/tclIOUtil.c,
     generic/tclPipe.c,
     generic/tclPosixStr.c,
     tests/io.test
     tests/io.test,
     tests/ioUtil.test,
     win/tclWinError.c

   >   1. ''Channel Transformations'' - generic/tclIOGT.c,
     tests/iogt.test

   >   1. ''Built-in Channel Types'' - compat/waitpid.c,
     doc/GetHostName.3,
     doc/GetOpnFl.3,
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406

407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
393
394
395
396
397
398
399

400
401
402
403
404
405
406
407
408
409

410






411
412

413
414
415
416

417
418
419
420
421
422
423







-










-
+
-
-
-
-
-
-


-




-







     library/tcltest/pkgIndex.tcl,
     tests/tcltest.test

   File System: 

   >   1. ''Pathname Management'' - doc/filename.n,
     doc/glob.n,
     doc/FileSystem.3,
     doc/SplitPath.3,
     doc/Translate.3,
     mac/tclMacFile.c,
     generic/tclFileName.c,
     tests/fileName.test,
     tests/unixFile.test,
     tests/winFile.test,
     unix/tclUnixFile.c,
     win/tclWinFile.c

   >   1. ''File System Access'' - doc/Access.3,
   >   1. ''File System Access'' - generic/tclFCmd.c,
     doc/GetCwd.3,
     doc/SetErrno.3,
     doc/Signal.3,
     generic/tclFCmd.c,
     generic/tclIOUtil.c,
     generic/tclPosixStr.c,
     mac/tclMacFCmd.c,
     tests/fCmd.test,
     tests/ioUtil.test,
     tests/macFCmd.test,
     tests/unixFCmd.test,
     tests/winFCmd.test,
     unix/tclUnixFCmd.c,
     win/tclWinError.c,
     win/tclWinFCmd.c

   Initialization, Script Library, and Autoloader: 

   >   1. doc/library.n,
     doc/tclvars.n,
     doc/unknown.n,
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
502
503
504
505
506
507
508

509
510
511
512
513
514
515







-







     tests/reg.test,
     tests/regexp.test,
     tools/uniClass.tcl

   UTF-8 String Management: 

   >   1. doc/ToUpper.3,
     doc/UniCharIsAlpha.3,
     doc/Utf.3,
     generic/tclUtf.c,
     tools/uniParse.tcl,
     tests/utf.test,
     win/tclWin32Dll.c

   Fundamental Parsing and Evaluation: 
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
554
555
556
557
558
559
560

561
562
563
564
565
566
567
568

569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587

588
589
590
591
592
593
594







-








-



















-







   >   1. compat/float.h,
     generic/tclCompCmds.c,
     generic/tclCompExpr.c,
     generic/tclCompile.c,
     generic/tclCompile.h,
     generic/tclExecute.c,
     generic/tclLiteral.c
     tests/appendComp.test,
     tests/compExpr-old.test,
     tests/compExpr.test,
     tests/compile.test,
     tests/execute.test,
     tests/expr.test,
     tests/for.test,
     tests/if.test,
     tests/incr.test,
     tests/stringComp.test,
     tests/while.test

   Threads: 

   >   1. doc/Thread.3,
     generic/tclThread.c,
     generic/tclThreadJoin.c,
     mac/tclMacThrd.c,
     mac/tclMacThrd.h,
     tests/thread.test,
     unix/tclUnixThrd.c,
     unix/tclUnixThrd.h,
     win/tclWinThrd.c,
     win/tclWinThrd.h

   Embedding Support: 

   >   1. doc/AppInit.3,
     doc/Tcl_Main.3,
     doc/Panic.3,
     doc/tclsh.1,
     generic/tclMain.c,
     generic/tclPanic.c,
     mac/tclMacAppInit.c,
     mac/tclMacPanic.c,
     unix/tclAppInit.c,
     win/tclAppInit.c
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
637
638
639
640
641
642
643

644
645
646
647
648
649
650







-







     tools/white.bmp,
     unix/Makefile.in,
     unix/aclocal.m4,
     unix/configure.in,
     unix/install-sh,
     unix/ldAix,
     unix/mkLinks,
     unix/mkLinks.tcl,
     unix/tcl.m4,
     unix/tcl.spec,
     unix/tclConfig.sh.in,
     win/Makefile.in,
     win/aclocal.m4,
     win/configure.in,
     win/makefile.vc,
678
679
680
681
682
683
684
685

686
687
688
689
690
691
692
693
669
670
671
672
673
674
675

676

677
678
679
680
681
682
683







-
+
-







   >   1. ''[[resource]]'' - doc/resource.n,
     doc/source.n,
     mac/tclMacResource.c,
     mac/tclMacResource.r,
     tests/resource.test,
     tests/source.test

   >   1. ''Mac-Specific Files'' - doc/Macintosh.3,
   >   1. ''Mac-Specific Files'' - mac/AppleScript.html
     mac/AppleScript.html
     mac/Background.doc
     mac/libmoto.doc
     mac/morefiles.doc
     mac/MW_TclAppleScriptHeader.h
     mac/MW_TclAppleScriptHeader.pch
     mac/MW_TclHeader.h
     mac/MW_TclHeader.pch
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
702
703
704
705
706
707
708

709
710
711
712
713
714
715







-







     mac/tclMacOSA.exp
     mac/tclMacOSA.r
     mac/tclMacProjects.sea.hqx
     mac/tclMacShLib.exp
     mac/tclMacTclCode.r
     mac/tclMacUnix.c
     mac/tclMacUtil.c
     mac/tcltkMacBuildSupport.sea.hqx
     tests/osa.test

~ Shared Files

The following files are shared by all of Tcl.  Any maintainer may
modify them as necessary to complete changes they are making to
their portion of Tcl.  Some of the following files define Tcl's
Changes to tip/17.tip.
1
2
3

4
5

6
7

8
9
10
11
12
13
14
1
2

3
4

5
6

7
8
9
10
11
12
13
14


-
+

-
+

-
+







TIP:            17
Title:          Redo Tcl's filesystem
Version:        $Revision: 1.18 $
Version:        $Revision: 1.15 $
Author:         Vince Darley <[email protected]>
State:          Final
State:          Draft
Type:           Project
Vote:           Done
Vote:           Pending
Created:        17-Nov-2000
Post-History:   
Tcl-Version:    8.4.0

~ Abstract

Many of the most exciting recent developments in Tcl have involved
Changes to tip/18.tip.
1
2
3

4
5

6
7

8
9
10
11
12
13
14
1
2

3
4

5
6

7
8
9
10
11
12
13
14


-
+

-
+

-
+







TIP:            18
Title:          Add Labels to Frames
Version:        $Revision: 2.2 $
Version:        $Revision: 2.0 $
Author:         Peter Spjuth <[email protected]>
State:          Accepted
State:          Draft
Type:           Project
Vote:           Done
Vote:           Pending
Created:        12-Dec-2000
Post-History:   
Tcl-Version:    8.4

~ Abstract

This TIP proposes to add a labelled frame widget to Tk.
Changes to tip/19.tip.
1
2
3

4
5
6
7
8
9
10
11
12
13
14
15
16
17
1
2

3
4
5
6
7
8
9

10
11
12
13
14
15
16


-
+






-







TIP:		19
Title:		Add a Text Changed Flag to Tk's Text Widget
Version:	$Revision: 1.5 $
Version:	$Revision: 1.4 $
Author:		Neil McKay <[email protected]>
State:		Accepted
Type:		Project
Vote:		Done
Created:	03-Jan-2001
Tcl-Version:	8.4a2
Obsoleted-By:	26
Post-History:

~Abstract

This TIP adds a ''text changed'' flag to the Tk text widget.  The flag
would initially be reset, but would be set whenever the contents of
the text widget changes.
Changes to tip/2.tip.
1
2
3

4
5
6
7
8
9
10
11
12
13
14
15
1
2

3
4
5
6


7
8
9
10
11
12
13


-
+



-
-







TIP:            2
Title:          TIP Guidelines
Version:        $Revision: 1.17 $
Version:        $Revision: 1.10 $
Author:         Andreas Kupries <[email protected]>
Author:         Donal K. Fellows <[email protected]>
Author:         Don Porter <[email protected]>
Author:         Mo DeJong <[email protected]>
Author:         Larry W. Virden <[email protected]>
State:          Draft
Type:           Process
Vote:           Pending
Created:        12-Sep-2000
Post-History:   

~ Abstract
31
32
33
34
35
36
37
38

39
40
41
42

43
44
45
46
47
48
49
50
29
30
31
32
33
34
35

36
37
38
39

40

41
42
43
44
45
46
47







-
+



-
+
-







documenting dissenting opinions.

Because the TIPs are maintained as text files under revision control,
their history is the historical record of the feature proposal.  This
historical record is available by the normal (CVS?) commands for
retrieving older revisions.  For those without direct access to the
CVS tree, you can browse the current and past TIP revisions via
http://www.cs.man.ac.uk/fellowsd-bin/TIP/ .
http://tip.web.site/

Further details on the arguments behind the evolution of the TIP
concept and formatting can be found in the archive of the ''tclcore''
mailing list at
mailing list at http://dev.scriptics.com/lists/tclcore/
http://www.geocrawler.com/redir-sf.php3?list=tcl-core .

~ Kinds of TIPs

There are three kinds of TIPs.  A project TIP describes a new (or
significantly updated) feature or implementation for Tcl.  An
informative TIP describes a Tcl design issue, or provides general
guidelines or information to the Tcl community, but does not propose a
67
68
69
70
71
72
73
74

75
76
77
78
79
80
81
64
65
66
67
68
69
70

71
72
73
74
75
76
77
78







-
+







If the TIP editor approves, he will assign the TIP a number, label it
as either project, process or informational, give it status ''Draft'',
and create and check-in the initial draft of the TIP.  The TIP editor
will not unreasonably deny a TIP.  Reasons for denying TIP status
include gross malformatting, inappropriate copyright, duplication of
effort, being technically unsound, or not in keeping with the Tcl
philosophy; the TCT and after that John Ousterhout
<ouster@pacbell.net> is the final arbitrator of the
<john.ousterhout@ajubasolutions.com> is the final arbitrator of the
latter, as defined in the charter ([0]).

Discussion concerning a TIP should initially be kept out of the
tclcore and tct mailing lists.  Instead, comments should be sent to,
and collected by, the TIP author, who has the responsibility to
incorporate these comments into the document.

198
199
200
201
202
203
204
205

206
207
208
209
210
211
212
195
196
197
198
199
200
201

202
203
204
205
206
207
208
209







-
+








(With thanks to William H. Duquette <[email protected]>
for suggesting this.)  Note that the TIP Editor is responsible for
allocating TIP numbers, so you can leave that unfilled.

|TIP:           ???
|Title:         The TIP Title as Plain Text
|Version:       $Revision: 1.17 $
|Version:       $Revision: 1.10 $
|Author:        Author Name <[email protected]>
|State:         Draft
|Type:          Project
|Tcl-Version:   8.4
|Vote:          Pending
|Created:       31-Feb-1999
|Post-History:
248
249
250
251
252
253
254
255

256
257
258
259
260
261
262
245
246
247
248
249
250
251

252
253
254
255
256
257
258
259







-
+







patches to be posted on that newsgroup.  If you want a patch to be
incorporated into the archive, please contact the TIP Editor.

----

~ Comments

 > From Don Porter  < [email protected] > :
 > From Don Porter  < [email protected] > : 

 > 1. It is confusing that "project" TIPs defined here do not
      correspond to "projects" defined in [0].

 > 2. The TIP Workflow section should mention the web-based
      drafting service [13] as another way for members of the
      community to add their comments to a draft TIP.
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
278
279
280
281
282
283
284





























285
286
287
288
289







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-





      incompatible with posting to comp.lang.tcl.announce, so
      earlier sections of this TIP should not indicate that including
      patches in the TIP is an acceptable practice.

 > 7. Should process TIPs be reserved for those proposals that
      revise [0] and require 2/3 support of the entire TCT?

From Mo DeJong:

It seems like we have a documentation problem with
respect to how a TIP becomes "un-rejected".

The text says:

 > ... may accept or reject a TIP or send it back to the author(s)
   for revision"

But the state transition diagram shows no way to go from
''Rejected'' to ''Draft''. What becomes of a TIP after it
is put up for a vote? If it is rejected, should the
author create a new TIP number or can they rewrite
the original TIP?

----

''Larry W. Virden writes:''  I would really find it useful
if upon submission of a TIP, a web page, perhaps on
the Tcl'ers Wiki or elsewhere, would be referenced in
the TIP itself.  This web page would contain a summary
of the discussion to date, perhaps containing urls
to relevant postings within the tct archives, etc.
This page could be used by those looking at the
archive to quickly determine the state of the discussion,
as well as the reasons for the final disposition of the
TIP.

----

~ Copyright

This document has been placed in the public domain.
Changes to tip/21.tip.
1
2
3

4
5

6
7
8
9
10
11
12
1
2

3
4

5
6
7
8
9
10
11
12


-
+

-
+







TIP:            21
Title:          Asymmetric Padding in the Pack and Grid Geometry Managers
Version:        $Revision: 1.6 $
Version:        $Revision: 1.5 $
Author:         D. Richard Hipp <[email protected]>
State:          Final
State:          Accepted
Type:           Project
Vote:           Done
Created:        14-Jan-2001
Post-History:   
Tcl-Version:    8.4

~ Abstract
Changes to tip/22.tip.
1
2
3

4
5
6
7
8

9
10

11
12
13
14


15
16
17
18
19
20
21
1
2

3
4

5


6
7

8
9
10


11
12
13
14
15
16
17
18
19


-
+

-

-
-
+

-
+


-
-
+
+







TIP:            22
Title:          Multiple Index Arguments to lindex
Version:        $Revision: 1.21 $
Version:        $Revision: 1.8 $
Author:         David Cuthbert <[email protected]>
Author:         Kevin Kenny <[email protected]>
Author:         Don Porter <[email protected]>
Author:         Donal K. Fellows <[email protected]>
State:          Accepted
State:          Draft
Type:           Project
Vote:           Done
Vote:           Pending
Created:        19-Jan-2001
Post-History:   
Discussions-To: news:comp.lang.tcl,mailto:[email protected]
Keywords:       lindex,multiple arguments,sublists
Discussions-To: news:comp.lang.tcl
Keywords:       {{{lindex {multiple arguments} sublists}}}
Tcl-Version:    8.4a2

~ Abstract

Obtaining access to elements of sublists in Tcl often requires nested
calls to the ''lindex'' command.  The indices are syntactically listed
in most-nested to least-nested order, which is the reverse from other
69
70
71
72
73
74
75
76
77

78
79
80

81
82

83
84
85
86
87

88
89

90
91
92
93
94
95

96
97
98
99
100
101
102
103
104
105
106
107
108

109
110
111

112
113
114
115

116
117

118
119
120
121

122
123
124
125
126


127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
67
68
69
70
71
72
73


74
75


76


77

78



79


80






81




82








83



84

85


86


87

88


89

90



91
92

93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108







































































109
110
111
112


113
114
115
116
117
118
119







-
-
+

-
-
+
-
-
+
-

-
-
-
+
-
-
+
-
-
-
-
-
-
+
-
-
-
-

-
-
-
-
-
-
-
-
+
-
-
-
+
-

-
-
+
-
-
+
-

-
-
+
-

-
-
-
+
+
-
















-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-




-
-







|result = range(temp, 0, length(temp) - 1);

Allowing the ''lindex'' command to accept multiple arguments would
allow this more-natural style of coding to be written in Tcl.

~ Specification

 1. Under this proposal, the syntax for the ''lindex'' command is to be
    modified to accept one of two forms:
 1. Allow ''lindex'' to accept an arbitrary number of arguments.

|     lindex list indexList

  > 1. The first argument (the ''list argument'') must be a proper Tcl
    or

       list.  No change is required from current behaviour.
|     lindex list index1 index2...

    > In either form of the command, the ''list'' parameter is
      expected to be a well-formed Tcl list.

  > 2. The remaining arguments (the ''index arguments'') must be
    > In the first form of the command, the ''indexList'' argument is
      expected to be a Tcl list comprising one or more list indices,
       proper list indices (either ''integer'', end, or
      each of which must be an integer, the literal string ''end'', or
      the literal string ''end-'' followed by an integer with no
      intervening whitespace.  The existing ''lindex'' command is a
      degenerate form of this first form, where the list comprises a
      single index.

       end-''integer'').
    > In the second form of the command, each of the ''index''
      arguments is expected to be a list index, which again may be an
      integer, the literal string ''end'', or the literal string
      ''end-'' followed by an integer with no intervening whitespace.

 2. In either form of the command, once the ''indexList'' parameter
    is expanded, there is a single ''list'' parameter and one or
    more ''index'' parameters.  If there is a single ''index''
    parameter ''N'', the behavior is identical to today's ''lindex''
    command, and the command returns the ''N''th element of
    ''list''; if ''N'' is less than zero or at least the length of
    the list, a null string is returned.

 2. When only one index argument is given, the behaviour is unchanged
 3. If more than one ''index'' parameter is given, then the behavior is
    defined recursively; the result of

    from the current ''lindex'' command.
|   lindex $list $index0 $index1 ...

  > or

 3. When multiple index arguments are given, the behaviour is defined
|   lindex $list [list $index0 $index1 ...]

    recursively as:
  > is indentical to that of

|   lindex [lindex $list $index0] $index1...

|lindex alist i0 i1 i2 ... === lindex [lindex alist i0] i1 i2 ...
  > or, equivalently,

|   lindex [lindex $list $index0] [list $index1...]

  > (This specification does not constrain the implementation, which
  > Note that this does not define any restrictions on the
    implementation, which may be recursive or iterative.
    may be iterative, recursive, or even expanded inline.)

 4. When an invalid index is given, an error of the form, ''bad index
    "invalid_index": must be integer or end?-integer?'', where
    ''invalid_index'' is the first invalid index encountered, must be
    returned.

 5. If the list argument is malformed, the error resulting from an
    attempt to convert the list argument to a list must be returned.
    This behaviour is unchanged from the current implementation.

~ Side Effects

 1. Whether the result of the ''lindex'' operation is successful, the
    underlying Tcl_Obj that represents the list argument may have its
    internal representation invalidated or changed to that of a list.

~ Discussion

Some attention must be paid to giving the ''lindex'' command adequate
performance.  In particular, the implementation should address the
common case of

|    lindex $list $i

where ''$i'' is a "pure" integer (that is, one whose string
representation has not yet been formed).  If the above specification
is followed naively, the flow will be as follows.

Since ''objc'' is three, ''objv[[2]]'' is expected to be a list.
Since it is not, it must be converted from its string representation.
It does not have one yet, so the string representation must be formed.
Now the string representation is parsed as a list.  An array (of
length one) of Tcl_Obj pointers is allocated to hold the list in
question, and a Tcl_Obj is allocated to hold the single element.
Memory is allocated to hold the element's string representation.
Now the ''lindex'' command converts the first element of the list to
an index (in this case an integer).

This elaborate ballet of type shimmering requires converting the
integer to a string and back again.  It also requires four calls to
''ckalloc:''

 1. Allocate a buffer for the string representation.

 2. Allocate the array of Tcl_Obj pointers for the list
    representation.

 3. Allocate the Tcl_Obj that represents the first (and only) element
    of the list.

 4. Allocate a buffer for the string representation of that element.

And at the end, the result is the same integer that was passed as a
parameter originally.

To avoid all this overhead in the common case, the proposed
implementation shall (in the case where ''objc==3'')

 1. Test whether ''objv[[2]]'' designates an object whose internal
    representation holds an integer.  If so, simply use it as an
    index.

 2. Test whether ''objv[[2]]'' designates an object whose internal
    representation holds a list.  If so, perform the recursive
    extraction of indexed elements from sublists described above.

 3. Form the string representation of ''objv[[2]]'' and test whether
    it is ''end'' or ''end-'' followed by an integer.  If so, use it
    as an index.

 4. Attempt to coerce ''objv[[2]]'' to an integer; if successful, use
    the result as an integer.

 5. Attempt to coerce ''objv[[2]]'' to a list; if successful, use the
    result as an index list.

 6. Report a malformed ''index'' argument; the ''indexList'' parameter
    is not a well-formed list.

This logic handles all the cases of singleton lists transparently; it
is effectively a simple-minded type inference that optimizes away
needless conversions.

Assuming that the related [33] is approved, this logic will most
likely be combined with the identical logic required in that proposal
for parsing ''index'' arguments to the ''lset'' command.

----

~ Comments

''Don Porter <[email protected]>''

 > I agree that it would be helpful to many programmers to
   provide a multi-dimensional array data structure that can
   be accessed in the manner described in this TIP.  In the
   ''struct'' module of ''tcllib'', several other data structures
   are being developed: graph, tree, queue, stack.  I would support
   adding another data structure to that module that provides an
   interface like the one described in this TIP, with the intent that
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268

269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
128
129
130
131
132
133
134


























135
136




137
138
































































139
140
141







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+

-
-
-
-


-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-



   packages to combine the primitives into more useful, more
   complex resources.

 > This TIP should also consider how any changes to [[lindex]] mesh
   with the whole [[listx]] overhaul of Tcl's [[list]] command that
   has been discussed.

''Dave Cuthbert <[email protected]> responds''

 > Don makes a good point -- with a good set of data structures in
   tcllib, the need for this TIP is lessened or even eliminated.
   Nonetheless, I see this as a way of implementing the structures he
   describes.  In other words, a more powerful primitive (which, in
   reality, adds fairly little complexity when measured in number of
   lines of code changed) would benefit these structures.

 > As for the [[listx]] overhaul, there are many competing proposals
   for the specification it is difficult to come up with a metric.  In
   writing this TIP, I assumed a vacuum -- that is, a listx command
   would not be added to the core in the near future.

''Donal K. Fellows <[email protected]> points out''

 > Although there is tcllib and [[listx]] to think about, they are
   certainly not reasons for rejecting this TIP out of hand.  The
   availability of tcllib is not currently anything like universal
   (not stating whether this is a good, bad or ugly thing) and all the
   [[listx]] work will need its own TIP to make it into the core (you
   tend to have availability problems if it is an extension.)  It is
   not as if the core is short of syntactic sugar right now (the
   [[foreach]] command is ample demonstration of this.)

''Don Porter <[email protected]> follows up''
 > ''Don Porter <[email protected]>''

 > I'll leave the discussion above in place so the history
   of this TIP is preserved, but I have withdrawn my
   objection.

----

There was quite a discussion on news:comp.lang.tcl about using lindex
to return multiple arguments.  For example:

| % set list {a {b1 b2} c d e}
| % lindex $list 1
| b1 b2
| % lindex $list 1 0
| {b1 b2} a
| % lindex $list {1 0}
| b1

In other words, the list index arguments can, themselves, be lists.
Only when the argument is a list would the "recursive selection"
procedure of the TIP be used.  For multiple arguments, the behaviour
is akin to

| lindex $list a b c  ->
|      list [lindex $list a] [lindex $list b] [lindex $list c]

''Summarised by Dave Cuthbert <[email protected]>''

''Donal K. Fellows <[email protected]> points out''

 > The problems with the above version of multiple indexing are that
   it loses the property that [[lindex]] always returns a single
   element (making writing robust code harder) and that it forces use
   of the [[list]] constructor a lot or inefficient type handling when
   some of the indices must be computed.  Then there is the whole
   question of what happens when you have indexes that are lists of
   lists, which is a major can of worms.

 > Luckily, we could always put this sort of behaviour into a separate
   command (e.g. called [[lselect]]) which addresses at least the
   majority of my concerns, and which (in my opinion) need not even
   form part of this TIP.

''Dave Cuthbert <[email protected]> adds''

 > I intentionally left [[lselect]] out of the original TIP (and it
   is still not present in the 02-April-2001 version).  As Donal points
   out, it is a major can of worms and, though there was general
   agreement on c.l.t that such a command would be useful, people had
   differing opinions on what form it should take.

 > Perhaps my view on TIPs is incorrect, but I try to include only
   sure-fire "yeah, we ought to have done that a few versions ago"
   items.

----

~ Notes on History of this TIP

''This TIP was originally written by Dave Cuthbert <[email protected]>,
but ownership has passed (beginning of April) to Kevin Kenny
<[email protected]>.''

This TIP underwent substantial revision in May of 2001, to add the
syntax where all the ''index'' parameters could be grouped as a list
rather than placed inline on the command line.

~ See Also

[33].

~ Copyright

This document has been placed in the public domain.
Changes to tip/23.tip.
1
2
3

4
5
6
7

8
9

10
11
12
13
14
15
16
1
2

3
4



5
6

7
8
9
10
11
12
13
14


-
+

-
-
-
+

-
+







TIP:            23
Title:          Tk Toolkit Functional Areas for Maintainer Assignments
Version:        $Revision: 1.19 $
Version:        $Revision: 1.5 $
Author:         Kevin Kenny <[email protected]>
Author:         Jim Ingham <[email protected]>
Author:         Don Porter <[email protected]>
State:          Accepted
State:          Draft
Type:           Process
Vote:           Done
Vote:           Pending
Created:        22-Jan-2001
Post-History:   

~ Abstract

This document proposes a division of the Tk toolkit's source code into
functional areas so that each area may be assigned to one or more
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58


59
60
61
62
63
64

65
66
67

68
69
70
71
72

73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90

91
92
93
94
95
96
97
98
99
100
101
102

103
104
105
106
107
108
109
110
111
112
113
114
115

116
117

118
119
120
121
122
123
124
125
126
127
128

129
130
131
132
133
134

135
136
137
138
139
140

141
142
143
144
145
146

147
148
149
150
151
152
153
154
155
156
157
158
159
160
161

162
163

164
165
166
167
168
169
170
171
172

173
174
175
176
177

178
179
180
181

182
183
184
185
186

187
188
189
190
191
192
193

194
195

196
197
198
199
200
201
202
203
204
205
206

207
208
209
210
211

212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232

233
234
235
236

237
238

239
240
241



242

243
244
245
246
247
248
249
250
251
252

253
254
255
256
257
258
259
260
261
262

263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278

279
280
281
282
283
284
285
286
287
288
289

290
291
292

293
294
295
296
297
298

299
300
301
302
303
304

305
306
307
308
309
310
311
312
313
314
315
316

317
318
319
320
321
322
323
324
325

326
327
328
329

330
331
332
333
334
335
336
337
338
339

340
341
342

343
344
345
346
347

348
349
350
351
352
353
354
355

356
357
358
359
360

361
362
363
364
365
366
367
368
369

370
371
372
373
374
375
376

377
378
379
380
381
382
383
384
385
386
387
388

389
390
391
392
393

394
395
396
397
398
399
400

401
402
403

404
405
406
407
408
409

410
411
412
413
414
415
416
417
418
419

420
421
422
423

424
425
426
427

428
429
430
431
432
433

434
435
436
437
438
439
440

441
442
443
444
445

446
447
448
449
450
451
452

453
454
455
456
457
458
459

460
461
462
463
464
465
466
467
468
469
470

471
472
473
474
475
476
477
478
479
480
481
482
483

484
485
486
487

488
489
490
491
492

493
494
495
496
497
498

499
500
501
502
503
504
505
506
507

508
509
510
511
512
513
514
515
516
517

518
519
520
521
522

523
524
525
526
527
528
529
530
531
532
533

534
535
536

537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553

554
555
556
557

558
559
560
561
562
563
564
31
32
33
34
35
36
37















38
39


40
41

42
43
44


45
46


47
48
49
50
51

52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69

70
71
72
73
74
75
76
77
78
79
80
81

82
83
84
85
86
87
88
89
90
91
92
93
94

95
96

97
98
99
100
101
102
103
104
105
106
107

108
109
110
111
112
113

114
115
116
117
118
119

120
121
122
123
124
125

126
127
128
129
130
131
132
133
134
135
136
137
138
139
140

141
142

143
144
145
146
147
148
149
150
151

152
153
154
155
156

157
158
159
160

161
162
163
164
165

166
167
168
169
170
171
172

173
174

175
176
177
178
179
180
181
182
183
184
185

186
187
188
189
190

191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211

212
213
214
215

216
217

218
219
220
221
222
223
224

225
226
227
228
229
230
231
232
233
234

235
236
237
238
239
240
241
242
243
244

245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260

261
262
263
264
265
266
267
268



269
270
271
272

273
274
275
276
277
278

279
280
281
282
283
284

285
286
287
288
289
290
291
292
293
294
295
296

297
298
299
300
301
302
303
304
305

306
307
308
309

310
311
312
313
314
315
316
317
318
319

320
321
322

323
324
325
326
327

328
329
330
331
332
333
334
335

336
337
338
339
340

341
342
343
344
345
346
347
348
349

350
351
352
353
354
355
356

357
358
359
360
361
362
363
364
365
366
367
368

369
370
371
372
373

374
375
376
377
378
379
380

381
382
383

384
385
386
387
388
389

390
391
392
393
394
395
396
397
398
399

400
401
402
403

404
405
406
407

408
409
410
411
412
413

414
415
416
417
418
419
420

421
422
423
424
425

426
427
428
429
430
431
432

433
434
435
436
437
438
439

440
441
442
443
444
445
446
447
448
449
450

451
452
453
454
455
456
457
458
459
460
461
462


463
464
465
466

467
468
469
470
471

472
473
474
475
476
477

478
479
480
481
482
483
484
485
486

487
488
489
490
491
492
493
494
495
496

497
498
499
500
501

502
503
504
505





506
507

508
509
510

511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527

528
529
530
531

532
533
534
535
536
537
538
539







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


-
-
+
+
-



-
-
+

-
-
+




-
+

















-
+











-
+












-
+

-
+










-
+





-
+





-
+





-
+














-
+

-
+








-
+




-
+



-
+




-
+






-
+

-
+










-
+




-
+




















-
+



-
+

-
+



+
+
+
-
+









-
+









-
+















-
+







-
-
-

+


-
+





-
+





-
+











-
+








-
+



-
+









-
+


-
+




-
+







-
+




-
+








-
+






-
+











-
+




-
+






-
+


-
+





-
+









-
+



-
+



-
+





-
+






-
+




-
+






-
+






-
+










-
+











-
-
+



-
+




-
+





-
+








-
+









-
+




-
+



-
-
-
-
-


-
+


-
+
















-
+



-
+







from source files to maintainers.  It also breaks out maintainers'
functional areas for the Tcl core.  This document attempts to develop
a similar mapping for the Tk toolkit.

Just as with [16], this document attempts to divide the Tk toolkit
into a set of the smallest sensible functional units.

One other factor, which was not addressed in [16], is that there is
considerably more platform dependent code in Tk than in Tcl, and it is
unreasonable to expect people to take ownership for pieces of code
that run on platforms they don't have access to.  However, we want to
make sure that the maintainer structure supports the cross-platform
nature of Tk.

To that end, in any area where there is both generic code, and
platform specific code, we propose that maintainers can sign up for
the generic code ''and'' code for one or more platforms.  By
overlapping the generic code, we ensure that the public interfaces to
Tk will stay consistent among the platforms, while not forcing
maintainers to presume expertise in code they can't even compile, much
less test or understand fully.

~ Proposal

The Tk toolkit shall be divided into the following eighty-six functional
units, each to be assigned one or more maintainers.  Each area will also
The Tk toolkit shall be divided into the following ninety-two functional
units, each to be assigned one or more maintainers:
be a Category in the SourceForge Tracker for Tk:

   Widgets: 

   >  1. ''Bindings'' -
     library/tk.tcl
   >  1. ''Standard bindings'' - library/tk.tcl

   >  2. ''Appearance'' -
     generic/default.h,
   >  2. ''Default appearance'' - generic/default.h,
     mac/tkMacDefault.h,
     unix/tkUnixDefault.h,
     win/tkWinDefault.h

   >  3. ''[*button] and [label]'' -
   >  3. ''button, checkbutton, radiobutton, label'' -
     doc/button.n,
     doc/checkbutton.n,
     doc/label.n,
     doc/radiobutton.n,
     generic/tkButton.c,
     generic/tkButton.h,
     library/button.tcl,
     mac/tkMacButton.c,
     unix/tkUnixButton.c,
     tests/butGeom.tcl,
     tests/butGeom2.tcl,
     tests/button.test,
     tests/unixButton.test,
     tests/winButton.test,
     win/rc/buttons.bmp,
     win/tkWinButton.c

   >  4. ''Canvas Basics'' -
   >  4. ''canvas (Basics)'' -
     doc/CanvPsY.3,
     doc/CanvTxtInfo.3,
     doc/CanvTkwin.3,
     doc/CrtItemType.3,
     doc/GetDash.3,
     doc/canvas.n,
     generic/tkCanvUtil.c,
     generic/tkCanvas.c,
     generic/tkCanvas.h,
     tests/canvas.test

   >  5. ''Canvas Items'' -
   >  5. ''canvas (Canvas items)'' -
     generic/tkCanvArc.c,
     generic/tkCanvBmap.c,
     generic/tkCanvImg.c,
     generic/tkCanvLine.c,
     generic/tkCanvPoly.c,
     generic/tkCanvText.c,
     generic/tkCanvWind.c,
     generic/tkRectOval.c,
     tests/arc.tcl,
     tests/canvImg.test,
     tests/canvRect.test,
     tests/canvText.test,
     tests/canvWind.test
     tests/canvWind.test,

   >  6. ''Canvas PostScript'' -
   >  6. ''canvas (PostScript printing)'' -
     generic/prolog.ps,
     generic/tkCanvPs.c,
     library/prolog.ps,
     tests/canvPs.test,
     tests/canvPsArc.tcl,
     tests/canvPsBmap.tcl,
     tests/canvPsGrph.tcl,
     tests/canvPsImg.tcl,
     tests/canvPsText.tcl

   >  7. ''[entry]'' -
   >  7. ''entry'' -
     doc/entry.n,
     generic/tkEntry.c,
     library/entry.tcl,
     tests/entry.test

   >  8. ''[frame] and [toplevel]'' -
   >  8. ''frame and toplevel'' -
     doc/frame.n,
     doc/toplevel.n,
     generic/tkFrame.c,
     tests/frame.test

   >  9. ''[listbox]'' -
   >  9. ''listbox'' -
     doc/listbox.n,
     generic/tkListbox.c,
     library/listbox.tcl,
     tests/listbox.test

   >  10. ''Generic Menus'' -
   >  10. ''menu, menubutton, and tk_popup (Generic)'' -
     doc/menu.n,
     doc/menubutton.n,
     doc/popup.n,
     generic/tkMacWinMenu.c,
     generic/tkMenu.c,
     generic/tkMenu.h,
     generic/tkMenuDraw.c,
     generic/tkMenubutton.c,
     generic/tkMenubutton.h,
     library/menu.tcl,
     library/tearoff.tcl,
     tests/macWinMenu.test,
     tests/menu.test,
     tests/menuDraw.test,
     tests/menubut.test
     tests/menubut.test,

   >  11. ''Mac Menus'' -
   >  11. ''menu, etc. (Macintosh)'' -
     mac/tkMacMDEF.c,
     mac/tkMacMDEF.r,
     mac/tkMacMenu.c,
     mac/tkMacMenu.r,
     mac/tkMacMenubutton.c,
     mac/tkMacMenus.c,
     tests/macMenu.test

   >  12. ''Unix Menus'' -
   >  12. ''menu, etc. (Unix)'' -
     tests/unixMenu.test,
     unix/tkUnixMenu.c,
     unix/tkUnixMenubu.c

   >  13. ''Win Menus'' -
   >  13. ''menu, etc. (Windows)'' -
     tests/winMenu.test,
     win/tkWinMenu.c

   >  14. ''[message]'' -
   >  14. ''message'' -
     doc/message.n,
     generic/tkMessage.c,
     tests/message.test

   >  15. ''[scale]'' -
   >  15. ''scale'' -
     doc/scale.n,
     generic/tkScale.c,
     generic/tkScale.h,
     library/scale.tcl,
     mac/tkMacScale.c,
     tests/scale.test,
     unix/tkUnixScale.c
     unix/tkUnixScale.c,

   >  16. ''[scrollbar]'' -
   >  16. ''scrollbar'' -
     doc/scrollbar.n,
     generic/tkScrollbar.c,
     generic/tkScrollbar.h,
     library/scrlbar.tcl,
     mac/tkMacScrlbr.c,
     tests/macscrollbar.test,
     tests/scrollbar.test,
     unix/tkUnixScrlbr.c,
     win/tkWinScrlbr.c

   >  17. ''[spinbox]'' -
   >  17. ''spinbox'' -
     doc/spinbox.n,
     library/spinbox.tcl,
     tests/spinbox.test

   >  18. ''[text]'' -
   >  18. ''text'' -
     doc/text.n,
     generic/tkText.c,
     generic/tkText.h
     generic/tkTextBTree.c,
     generic/tkTextDisp.c,
     generic/tkTextImage.c,
     generic/tkTextIndex.c,
     generic/tkTextMark.c,
     generic/tkTextTag.c,
     generic/tkTextWind.c,
     library/text.tcl,
     tests/text.test,
     tests/textBTree.test,
     tests/textDisp.test,
     tests/textImage.test,
     tests/textIndex.test,
     tests/textMark.test,
     tests/textTag.test,
     tests/textWind.test

   >  19. ''Menubars (obsolete)'' -
   >  19. ''tk_menubar (Deprecated)'' -
     doc/menubar.n,
     library/obsolete.tcl

   >  20. ''[tk_optionMenu]'' -
   >  20. ''tk_optionMenu'' -
     doc/optionMenu.n,
     library/optMenu.tcl
     library/optionMenu.tcl

   Widget Options: 

   >  1. ''Standard options'' -
     doc/options.n

   >  1. ''Option Parsing'' -
   >  2. ''Option parsing'' -
     doc/ConfigWidg.3,
     doc/SetOptions.3,
     generic/tkConfig.c,
     generic/tkOldConfig.c,
     mac/tkMacConfig.c,
     unix/tkUnixConfig.c,
     tests/config.test,
     win/tkWinConfig.c

   >  2. ''Relief'' -
   >  3. ''Relief'' -
     doc/3DBorder.3,
     doc/GetRelief.3,
     generic/tk3d.c,
     generic/tk3d.h,
     unix/tkUnix3d.c,
     tests/bevel.tcl,
     tests/border.tcl,
     win/tkWin3d.c

   >  3. ''Built-in Bitmaps'' -
   >  4. ''Standard bitmaps'' -
     bitmaps/error.bmp,
     bitmaps/gray12.bmp,
     bitmaps/gray25.bmp,
     bitmaps/gray50.bmp,
     bitmaps/gray75.bmp,
     bitmaps/hourglass.bmp,
     bitmaps/info.bmp,
     bitmaps/questhead.bmp,
     bitmaps/question.bmp,
     bitmaps/warning.bmp,
     doc/GetBitmap.3,
     generic/tkBitmap.c,
     mac/tkMacBitmap.c,
     tests/bitmap.test

   >  4. ''Conversions From String'' -
   >  5. ''Anchors, line styles, justification, and metrics'' -
     doc/GetAnchor.3,
     doc/GetCapStyl.3,
     doc/GetJoinStl.3,
     doc/GetJustify.3,
     doc/GetPixels.3,
     doc/GetUid.3,
     generic/tkGet.c,
     tests/get.test

   >  5. ''Objects'' - 
     generic/tkObj.c,
     tests/get.test,
     tests/obj.test

   >  6. ''Utility Functions'' -
   >  6. ''Focus highlights and scroll quantities'' -
     doc/DrawFocHlt.3,
     doc/GetScroll.3,
     generic/tkUtil.c,
     tests/util.test

   >  7. ''Colormaps and Visuals'' -
   >  7. ''Colormaps and visuals'' -
     doc/GetClrmap.3,
     doc/GetVisual.3,
     generic/tkVisual.c,
     tests/visual.test

   >  8. ''Color Names'' -
   >  8. ''Color names'' -
     doc/GetColor.3,
     doc/colors.n,
     generic/tkColor.c,
     generic/tkColor.h,
     mac/tkMacColor.c,
     unix/tkUnixColor.c,
     tests/cmap.tcl,
     tests/color.test,
     win/tkWinColor.c,
     xlib/colors.c

   >  9. ''Cursor Names'' -
   >  9. ''Cursor names'' -
     doc/GetCursor.3,
     doc/cursors.n,
     generic/tkCursor.c,
     mac/tkMacCursor.c,
     mac/tkMacCursors.r,
     mac/tkMacXCursors.r,
     unix/tkUnixCursor.c,
     tests/cursor.test,
     win/rc/cursor*.cur,
     win/rc/cursor*.cur
     win/tkWinCursor.c,
     xlib/X11/cursorfont.h

   >  10. ''Key Symbols'' -
   >  10. ''Key symbols'' -
     doc/keysyms.n,
     mac/tkMacKeyboard.c,
     unix/tkUnixKey.c,
     win/tkWinKey.c,
     xlib/X11/keysym.h,
     xlib/X11/keysymdef.h

   Standard Dialogs: 

   >  1. ''Generic Dialog Support'' -
   >  1. ''Common code'' -
     library/comdlg.tcl

   >  2. ''[tk_chooseColor]'' -
   >  2. ''Color selection'' -
     doc/chooseColor.n,
     library/clrpick.tcl,
     tests/clrpick.test

   >  3. ''[tk_dialog]'' -
   >  3. ''tk_dialog'' -
     doc/dialog.n,
     library/dialog.tcl,
     mac/tkMacDialog.c,
     tests/winDialog.test,
     unix/tkUnixDialog.c,
     win/tkWinDialog.c

   >  4. ''[tk_chooseDirectory]'' -
   >  4. ''Directory selection'' -
     doc/chooseDirectory.n,
     library/choosedir.tcl,
     tests/choosedir.test

   >  5. ''[tk_get*File]'' -
   >  5. ''File selection'' -
     doc/getOpenFile.n,
     generic/tkFileFilter.c,
     generic/tkFileFilter.h,
     library/tkfbox.tcl,
     library/xmfbox.tcl,
     tests/filebox.test,
     tests/xmfbox.test

   >  6. ''[tk_messageBox]'' -
   >  6. ''tk_messageBox'' -
     doc/messageBox.n,
     library/msgbox.tcl,
     tests/msgbox.test

   Images: 

   >  1. ''Image Basics'' -
   >  1. ''Basic image support'' -
     doc/CrtImgType.3,
     doc/DeleteImg.3,
     doc/GetImage.3,
     doc/ImgChanged.3,
     doc/NameOfImg.3,
     doc/image.n,
     generic/tkImage.c,
     generic/tkImgUtil.c,
     generic/tkStubImg.c,
     tests/image.test

   >  2. ''Bitmap Images'' -
   >  2. ''Bitmap images'' -
     doc/bitmap.n,
     generic/tkImgBmap.c,
     tests/imgBmap.test

   >  3. ''Photo Images'' -
   >  3. ''Photo images'' -
     doc/CrtPhImgFmt.3,
     doc/FindPhoto.3,
     doc/photo.n,
     generic/tkImgPhoto.c,
     tests/imgPhoto.test

   >  4. ''Photo Image|GIF'' -
   >  4. ''GIF support'' -
     generic/tkImgGIF.c

   >  5. ''Photo Image|PPM'' -
   >  5. ''PPM support'' -
     generic/tkImgPPM.c,
     tests/imgPPM.test

   Fonts: 

   >  1. ''Generic Fonts'' -
   >  1. ''Fonts'' -
     doc/FontId.3,
     doc/GetFont.3,
     doc/MeasureChar.3,
     doc/TextLayout.3,
     doc/font.n,
     generic/tkFont.c,
     generic/tkFont.h,
     tests/font.test

   >  2. ''Mac Fonts'' -
   >  2. ''Macintosh font support'' -
     mac/tkMacFont.c,
     tests/macFont.test

   >  3. ''Unix Fonts'' -
   >  3. ''Unix font support'' -
     tests/unixFont.test,
     unix/tkUnixFont.c

   >  4. ''Win Fonts'' -
   >  4. ''Windows font support'' -
     tests/winFont.test,
     win/tkWinFont.c

   Geometry management: 

   >  1. ''Geometry Management'' -
   >  1. ''Common geometry management'' -
     doc/GeomReq.3,
     doc/MaintGeom.3,
     doc/ManageGeom.3,
     generic/tkGeometry.c,
     tests/geometry.test

   >  2. ''[grid]'' -
   >  2. ''grid'' -
     doc/grid.n,
     generic/tkGrid.c,
     tests/grid.test

   >  3. ''[pack]'' -
   >  3. ''pack'' -
     doc/pack-old.n,
     doc/pack.n,
     generic/tkPack.c,
     tests/oldpack.test,
     tests/pack.test

   >  4. ''[place]'' -
   >  4. ''place'' -
     doc/place.n,
     generic/tkPlace.c,
     tests/place.test

   Selection and Clipboard: 

   >  1. ''[clipboard]'' -
   >  1. ''clipboard'' -
     doc/Clipboard.3,
     doc/clipboard.n,
     generic/tkClipboard.c,
     mac/tkMacClipboard.c,
     tests/clipboard.test,
     tests/unixSelect.test,
     tests/winClipboard.test,
     unix/tkUnixSelect.c,
     win/tkWinClipboard.c

   >  2. ''[selection]'' -
   >  2. ''selection'' -
     doc/ClrSelect.3,
     doc/CrtSelHdlr.3,
     doc/GetSelect.3,
     doc/OwnSelect.3,
     doc/selection.n,
     generic/tkSelect.c,
     generic/tkSelect.h,
     tests/select.test

   Other Tk commands: 

    >  1. ''[console]'' -
     doc/console.n
    >  1. ''console'' --
     generic/tkConsole.c,
     library/console.tcl

    >  2. ''[focus]'' -
    >  2. ''focus'' -
     doc/focus.n,
     generic/tkFocus.c,
     tests/focus.test

    >  3. ''[grab]'' -
    >  3. ''grab'' -
     doc/Grab.3,
     doc/grab.n,
     generic/tkGrab.c,
     tests/grab.test

    >  4. ''[option]'' -
    >  4. ''option'' -
     doc/AddOption.3,
     doc/GetOption.3,
     doc/option.n,
     generic/tkOption.c,
     tests/option.file1,
     tests/option.file2,
     tests/option.test

   >  5. ''[send]'' -
   >  5. ''send'' -
     doc/SetAppName.3,
     doc/send.n,
     mac/tkMacSend.c,
     tests/send.test,
     tests/unixSend.test,
     tests/winSend.test,
     unix/tkUnixSend.c,
     win/tkWinSend.c

   >  6. ''[tk_focus*]'' -
   >  6. ''tk_focusNext and friends'' -
     doc/focusNext.n,
     library/focus.tcl,
     tests/focusTcl.test

   >  7. ''[tk_setPalette]'' -
   >  7. ''tk_palette'' -
     doc/palette.n,
     library/palette.tcl

   >  8. ''Safe Tk'' -
     doc/loadTk.n,
     library/safetk.tcl,
     tests/safe.test

   Low-level Tk functions: 

   >  1. ''Geometry Functions'' -
   >  1. ''Geometry'' -
     generic/tkTrig.c

   >  2. ''Tk_Win Functions'' -
   >  2. ''Tk_Win functions'' -
     doc/ConfigWind.3,
     doc/CrtWindow.3,
     doc/IdToWindow.3,
     doc/MainWin.3,
     doc/MapWindow.3,
     doc/Name.3,
     doc/Restack.3,
     doc/SetClass.3,
     doc/SetClassProcs.3,
     doc/SetVisual.3,
     doc/StrictMotif.3,
     doc/Tk_Init.3,
     doc/WindowId.3,
     generic/tkWindow.c,
     tests/window.test

   >  3. ''Graphic Contexts'' -
   >  3. ''Graphic contexts'' -
     doc/GetGC.3,
     generic/tkGC.c

   >  4. ''Generic Window Operations'' -
   >  4. ''Basic window manipulations'' -
     doc/CoordToWin.3,
     doc/FreeXId.3,
     doc/GetHINSTANCE.3,
     doc/GetHWND.3,
     doc/GetPixmap.3,
     doc/GetRootCrd.3,
     doc/GetVRoot.3,
581
582
583
584
585
586
587
588

589
590
591
592
593
594
595
596
597
598
599
600


601
602
603
604
605
606
607
608
609
610
611

612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630

631
632
633
634
635
636
637
638
639
640
641

642
643
644
645
646
647
648
649
650
651
652
653
654
655

656
657
658
659

660

661
662
663
664
665
666
667

668
669
670
671
672
673
674
675

676
677
678
679
680
681
682
556
557
558
559
560
561
562

563
564
565
566
567
568
569
570
571
572
573


574
575
576
577
578
579
580
581
582
583
584
585

586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604

605
606
607
608
609
610
611
612
613
614
615

616
617
618
619
620
621
622
623
624
625
626
627
628
629

630
631
632
633

634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651

652
653
654
655
656
657
658
659







-
+










-
-
+
+










-
+


















-
+










-
+













-
+



-
+

+







+







-
+







     tests/cmds.test,
     tests/id.test,
     tests/raise.test,
     tests/tk.test,
     tests/winfo.test,
     xlib/xgc.c

   >  5. ''Mac Window Operations'' -
   >  5. ''Macintosh window operations'' -
     mac/tkMacAppearanceStubs.c,
     mac/tkMacDraw.c,
     mac/tkMacEmbed.c,
     mac/tkMacHLEvents.c,
     mac/tkMacRegion.c,
     mac/tkMacSubwindows.c,
     mac/tkMacWindowMgr.c,
     mac/tkMacWm.c,
     mac/tkMacXStubs.c,
     tests/macEmbed.test

   >  6. ''Unix Window Operations'' -
     
   >  6. ''Unix window operations'' -
     tests/unixEmbed.test,
     tests/unixWm.test,
     unix/tkUnix.c,
     unix/tkUnixDraw.c,
     unix/tkUnixEmbed.c,
     unix/tkUnixEvent.c,
     unix/tkUnixFocus.c,
     unix/tkUnixWm.c,
     unix/tkUnixXId.c

   >  7. ''Win Window Operations'' -
   >  7. ''Windows window operations'' -
     tests/WinWm.test,
     win/stubs.c,
     win/tkWinDraw.c,
     win/tkWinEmbed.c,
     win/tkWinImage.c,
     win/tkWinPixmap.c,
     win/tkWinPointer.c,
     win/tkWinRegion.c,
     win/tkWinWindow.c,
     win/tkWinWm.c,
     win/tkWinX.c

   >  8. ''Events'' -
     doc/BindTable.3,
     doc/event.n,
     generic/tkBind.c,
     tests/bind.test

   >  9. ''Event Loop'' -
   >  9. ''Event loop'' -
     doc/CrtCmHdlr.3,
     doc/CrtGenHdlr.3,
     doc/EventHndlr.3,
     doc/HandleEvent.3,
     doc/MainLoop.3,
     doc/QWinEvent.3,
     doc/RestrictEv.3,
     generic/tkEvent.c,
     tests/event.test

   >  10. ''Error Handling'' -
   >  10. ''Error handling'' -
     doc/CrtErrHdlr.3,
     doc/tkerror.n,
     generic/tkError.c,
     library/bgerror.tcl,
     tests/bgerror.test

   >  11. ''Atoms'' -
     doc/InternAtom.3,
     generic/tkAtom.c,
     xlib/X11/Xatom.h

   Shells: 

   >  1. ''Argv Parsing'' -
   >  1. ''Argc/argv parsing'' -
     doc/ParseArgv.3,
     generic/tkArgv.c

   >  2. ''Application Embedding'' -
   >  2. ''Application embedding'' -
     doc/Tk_Main.3,
     doc/loadTk.n,
     generic/tkInitScript.h,
     generic/tkMain.c,
     mac/tkMacInit.c,
     unix/tkUnixInit.c,
     win/tkWin32DLL.c,
     win/tkWinInit.c,
     tests/main.test,
     tests/safe.test

   >  3. ''wish'' -
     doc/wish.1,
     mac/tkMacAppInit.c,
     unix/tkAppInit.c,
     win/winMain.c

   >  4. ''Mac DND Tclets'' -
   >  4. ''Drag and Drop Tclets (Macintosh)'' -
     mac/tclets.r,
     mac/tclets.tcl

   Demonstrations: 

   >  1. ''Widget Tour'' -
     library/demos/arrow.tcl,
724
725
726
727
728
729
730
731

732
733
734
735

736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752



















753
754
755
756
757
758
759
760
761
762
763
764
765
766

767
768

769
770
771
772
773

774
775
776
777
778
779
780
781
782
783

784
785
786
787
788
789
790
791
792
793
794
795

796
797
798
799

800
801
802
803
804

805
806
807
808
809
810
811
701
702
703
704
705
706
707

708
709
710
711

712
713
714
715
716
717
718
719
720
721
722







723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749


750

751

752
753

754
755
756
757
758

759
760
761
762
763
764
765
766
767
768

769
770
771
772
773
774
775
776
777
778
779
780

781
782
783
784
785
786
787
788
789
790

791
792
793
794
795
796
797
798







-
+



-
+










-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








-
-

-

-
+

-
+




-
+









-
+











-
+




+




-
+







     library/demos/images/gray25.bmp,
     library/demos/images/letters.bmp,
     library/demos/images/noletter.bmp,
     library/demos/images/pattern.bmp,
     library/demos/images/tcllogo.gif,
     library/demos/images/teapot.ppm

   >  2. ''Square Demo'' -
   >  2. ''The square extension'' -
     generic/tkSquare.c,
     library/demos/square

   >  3. ''Other Demos'' -
   >  3. ''Miscellaneous demos'' -
     library/demos/browse,
     library/demos/hello,
     library/demos/ixset,
     library/demos/rmt,
     library/demos/rolodex,
     library/demos/tcolor,
     library/demos/timer

   Localization: 

   >  1. ''L10N'' -
     library/msgs/de.msg,
     library/msgs/el.msg,
     library/msgs/en.msg,
     library/msgs/es.msg,
     library/msgs/fr.msg,
     library/msgs/it.msg,
   >  1. ''German'' -
     library/msgs/de.msg

   >  2. ''Greek'' -
     library/msgs/el.msg

   >  3. ''English'' -
     library/msgs/en.msg

   >  4. ''Spanish'' -
     library/msgs/es.msg

   >  5. ''French'' -
     library/msgs/fr.msg

   >  6. ''Italian'' -
     library/msgs/it.msg

   >  7. ''Dutch'' -
     library/msgs/nl.msg

   Release Engineering: 

   >  1. ''Release Notes'' -
     README,
     */README,
     */*/README,
     changes,
     license.terms,
     tk4.0.ps,
     doc/options.n
     mac/bugs.doc,
     tests/bugs.tcl
     tests/bugs.tcl,

   >  2. ''Portability'' -
   >  2. ''Portability Support'' -
     compat/limits.h,
     compat/stdlib.h,
     compat/unistd.h

   >  3. ''X11 Emulation'' -
   >  3. ''X11 Emulation Support'' -,
     xlib/X11/X.h,
     xlib/X11/Xfuncproto.h,
     xlib/X11/Xlib.h,
     xlib/X11/Xutil.h,
     xlib/xbytes.h,
     xlib/xdraw.c,
     xlib/ximage.c,
     xlib/xutil.c

   >  4. ''Mac Build'' -
   >  4. ''Macintosh Configuration and Build Tools'' -
     mac/MW_TkHeader.h,
     mac/MW_TkHeader.pch,
     mac/MW_TkOldImgHeader.h,
     mac/MW_TkTestHeader.h,
     mac/MW_TkTestHeader.pch,
     mac/tkMacApplication.r,
     mac/tkMacLibrary.r,
     mac/tkMacProjects.sea.hqx,
     mac/tkMacResource.r,
     mac/tkMacShlib.exp

   >  5. ''Unix Build'' -
   >  5. ''Unix configuration and Build Tools'' -
     unix/Makefile.in,
     unix/aclocal.m4,
     unix/configure.in,
     unix/install-sh,
     unix/mkLinks,
     unix/tcl.m4,
     unix/tk.spec,
     unix/tkConfig.sh.in

   >  6. ''Win Build'' -
   >  6. ''Windows Configuration and Build Tools'' -
     win/Makefile.in,
     win/aclocal.m4,
     win/configure.in,
     win/makefile.vc,
     win/mkd.bat,
     win/rc/tk.rc,
     win/rc/tk_base.rc,
819
820
821
822
823
824
825
826

827
828
829
830
831
832
833
806
807
808
809
810
811
812

813
814
815
816
817
818
819
820







-
+







     generic/tkTest.c,
     mac/tkMacTest.c,
     win/tkWinTest.c,
     tests/all.tcl,
     tests/defs.tcl,
     tests/visual_bb.test

   >  8. ''Logos'' -
   >  8. ''Logos and Branding'' -
     library/images/logo.eps,
     library/images/logo100.gif,
     library/images/logo64.gif,
     library/images/logoLarge.gif,
     library/images/logoMed.gif,
     library/images/pwrdLogo.eps,
     library/images/pwrdLogo100.gif,
843
844
845
846
847
848
849

850
851
852
853
854
855
856
857

858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
830
831
832
833
834
835
836
837
838
839

840
841
842
843

844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864


865

866
867


































868
869
870







+


-




-
+




















-
-

-


-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-




The following files are shared by all of Tk.  Any maintainer may
modify them as necessary to complete changes they are making to
their portion of Tk.  Some of the following files define Tk's
API and should be changed only with TCT approval.

   * ChangeLog,
     changes,
     doc/tkvars.n,
     doc/TkInitStubs.3,
     doc/man.macros,
     generic/tk.decls,
     generic/tk.h,
     generic/tkInt.decls,
     generic/tkInt.h,
     generic/tkPort.h,
     generic/tkPort.h
     generic/tkStubLib.c,
     mac/tkMac.h,
     mac/tkMacInt.h,
     mac/tkMacPort.h,
     unix/tkUnixInt.h,
     unix/tkUnixPort.h,
     win/tkWinInt.h,
     win/tkWinPort.h

~ Generated Files

The following files are generated, so they don't need maintainers.

   * generic/ks_names.h,
     generic/tkDecls.h,
     generic/tkIntDecls.h,
     generic/tkIntPlatDecls.h,
     generic/tkIntXlibDecls.h,
     generic/tkPlatDecls.h,
     generic/tkStubInit.c,
     library/demos/tclIndex
     library/tclIndex
     unix/configure,
     unix/mkLinks,
     win/configure

~ Platform Dependencies

In addition to the division into functional areas, responsibility for
a given area can also be qualified by one or more ''platform''
specifiers.  Some areas, like ''Windows Configuration and Build
Tools'' are obviously platform specific, so the qualification is
unnecessary.  Others, like ''Canvas Items'', are wholly generic.  But
others, like ''Button'', ''Scale'' or ''Scrollbar'' contain code for
all platforms.

A maintainer can sign up for one of these latter areas, but specify
support for only one platform.  This means that that person will be
responsible for the generic code in this area, in conjunction with the
other platform maintainers in this area, and the platform specific
code in that area.

The point behind sharing the generic code among all the maintainers is
so that any changes to the Tk visible face of the widget be designed
in concert for all platforms.  Therefore, it is the responsibility of
a platform maintainer for one platform who is sponsering a new feature
for that area to work with the other platform maintainers to ensure
that the feature is implemented on all platforms.  One of the
strengths of Tk is its cross-platform nature, and one of the
maintainer's jobs is to ensure that this continues.

Procedurally, the maintainer will be listed as ''Button Widget -
Macintosh'', etc.  A maintainer for a given area can sign up for one
or more platforms.  Due to the good design of the Tk's platform
dependencies, determining which files are generic, and which are
platform specific is trivial.  The generic ones are in the ''generic''
directory, the Mac ones in the ''mac'' directory, etc.  Similarly, an
area which has NO files in the mac, win, or unix directories is a
generic area, and no qualifiers are needed.

~ Copyright

This document has been placed in the public domain.
Changes to tip/24.tip.
1
2
3

4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

42
43
44
45

46
47

48
49

50
51

52
53

54
55
56
57
58

59
60

61
62
63
64
65

66
67

68
69

70
71

72
73

74
75
76
77
78
79

80
81

82
83
84

85
86
87
88

89
90
91

92
93

94
95
96

97
98
99

100
101
102
103
104
105

106
107

108
109

110
111

112
113

114
115

116
117
118



119
120
121
122
123
124









125
126

127
128
129
130
131

132
133
134
135
136
137

138
139

140
141
142
143
144
145

146
147
148
149
150




151

152
153

154
155

156
157

158
159
160
161
162

163
164
165
166
167

168
169
170
171

172
173
174
175
176
177

178
179
180

181
182

183
184
185

186
187
188
189
190
191
192
193

194
195
196

































197
198
199
200
201
202
203
204
205
1
2

3
4




5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21












22
23
24

25


26

27
28

29
30

31
32

33
34

35



36

37
38

39



40

41
42

43
44

45
46

47
48

49




50

51
52

53
54


55

56


57

58

59
60

61
62


63

64

65




66

67
68

69
70

71
72

73
74

75
76

77
78


79
80
81
82





83
84
85
86
87
88
89
90
91
92

93



94

95




96

97
98

99




100

101




102
103
104
105
106

107
108

109
110

111
112

113



114

115



116

117


118

119




120

121

122

123
124

125

126

127

128
129
130
131
132
133
134
135



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177


-
+

-
-
-
-

















-
-
-
-
-
-
-
-
-
-
-
-



-
+
-
-

-
+

-
+

-
+

-
+

-
+
-
-
-

-
+

-
+
-
-
-

-
+

-
+

-
+

-
+

-
+
-
-
-
-

-
+

-
+

-
-
+
-

-
-
+
-

-
+

-
+

-
-
+
-

-
+
-
-
-
-

-
+

-
+

-
+

-
+

-
+

-
+

-
-
+
+
+

-
-
-
-
-
+
+
+
+
+
+
+
+
+

-
+
-
-
-

-
+
-
-
-
-

-
+

-
+
-
-
-
-

-
+
-
-
-
-

+
+
+
+
-
+

-
+

-
+

-
+
-
-
-

-
+
-
-
-

-
+
-
-

-
+
-
-
-
-

-
+
-

-
+

-
+
-

-
+
-







+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+









TIP:            24
Title:          Tcl Maintainer Assignments
Version:        $Revision: 1.24 $
Version:        $Revision: 1.1 $
Author:         Don Porter <[email protected]>
Author:         Donal K. Fellows <[email protected]>
Author:         Kevin B KENNY <[email protected]>
Author:         <[email protected]>
Author:         Jeff Hobbs <[email protected]>
State:          Draft
Type:           Informative
Vote:           Pending
Created:        29-Jan-2001
Post-History:   

~ Abstract

This document keeps a record of who maintains each functional area
of Tcl ([16]).

~ Assignments

Listed below are Tcl's 52 functional units, in the same order as
in [16].  See [16] for the precise definition of what code belongs to
what area.  The area names are changed to match the Categories in Tcl's
SourceForge Bug Manager (http://sourceforge.net/bugs/?group_id=10894).

Note that an area can have more than one maintainer.  When the
maintenance of the entire area requires several types of
expertise, it is desirable to have more than one maintainer.

In several of the areas below, there are maintainers who have
volunteered to provide special expertise (for example, assistance
with programming and testing for the Mac platform) to assist
in maintaining an area, but who have not taken on the whole area.
These maintainers are indicated by a parenthesized designation
of their expertise.

For each of Tcl's functional units, the following maintainers are
assigned:

   1. ''Notifier'' - Daniel Steffen <[email protected]> (Mac),
   1. ''Notifier'' - 
                     Jim Ingham <[email protected]> (Mac),
                     Kevin Kenny <[email protected]> (Win32, Solaris, HP-UX)

   2. ''Event Loops'' - Jan Nijtmans <[email protected]>, Jeff Hobbs <[email protected]>
   1. ''Event Loops'' -

   3. ''Timer Events'' - Kevin Kenny <[email protected]>, Jeff Hobbs <[email protected]>
   1. ''Timer Events'' -

   4. ''Async Events'' - 
   1. ''Async Events'' - 

   5. ''XT Notifier'' - 
   1. ''XT Notifier'' - 

   6. ''Time Measurement'' -  Kevin Kenny <[email protected]>,
   1. ''Time Measurement'' - 
                              Daniel Steffen <[email protected]> (Mac),
                              Jim Ingham <[email protected]> (Mac),
			      Jeff Hobbs <[email protected]>

   7. ''Variables'' - Miguel Sofer <[email protected]>, Jeff Hobbs <[email protected]>
   1. ''Variables'' - 

   8. ''Environment Variables'' -
   1. ''Environment Variables'' - 
        Daniel Steffen <[email protected]> (Mac),
        Jim Ingham <[email protected]> (Mac)
	Jeff Hobbs <[email protected]>

   9. ''Linked C Variables'' - Jeff Hobbs <[email protected]>
   1. ''Linked C Variables'' - 

   10. ''Objects'' - Miguel Sofer <[email protected]>, Jeff Hobbs <[email protected]>
   1. ''Compiler and Objects'' - 

   11. ''Conversions from String'' - Jeff Hobbs <[email protected]>
   1. ''Conversions from String'' - 

   12. ''ByteArray Objects'' - Jan Nijtmans <[email protected]>, Jeff Hobbs <[email protected]>
   1. ''ByteArray Objects'' - 

   13. ''Index Object'' - Jan Nijtmans <[email protected]>, Jeff Hobbs <[email protected]>
   1. ''Index Object'' - 

   14. ''List Object'' - Jan Nijtmans <[email protected]>, Jeff Hobbs <[email protected]>

   15. ''Commands A-H'' - Donal K. Fellows <[email protected]>, Jeff Hobbs <[email protected]>

   16. ''Commands I-L'' - Donal K. Fellows <[email protected]>, Jeff Hobbs <[email protected]>
   1. ''List Object'' - 

   17. ''Commands M-Z'' - Donal K. Fellows <[email protected]>, Jeff Hobbs <[email protected]>
   1. ''Commands A-H'' - 

   18. ''[[history]]'' - Jeff Hobbs <[email protected]>

   1. ''Commands I-L'' - 
   19. ''[[interp]]'' - Jeff Hobbs <[email protected]>

   20. ''[[namespace]]'' - Miguel Sofer <[email protected]>, Jeff Hobbs <[email protected]>

   1. ''Commands M-Z'' - 
   21. ''[[proc]] and [[uplevel]]'' - Miguel Sofer <[email protected]>, Jeff Hobbs <[email protected]>

   22. ''[[scan]]'' - Jeff Hobbs <[email protected]>
   1. ''History'' - 

   23. ''Channel Commands'' - Andreas Kupries <[email protected]>, Jeff Hobbs <[email protected]>
   1. ''Interp Command'' - 

   24. ''Channel System'' - Andreas Kupries <[email protected]>, Jeff Hobbs <[email protected]>

   1. ''Namespaces'' - 
   25. ''Channel Transforms'' - Andreas Kupries <[email protected]>, Jeff Hobbs <[email protected]>

   26. ''Channel Types'' - Andreas Kupries <[email protected]>,
   1. ''Procedures'' - 
                          Rolf Schroedter <[email protected]> (WinSerial),
                          Daniel Steffen <[email protected]> (Mac),
                          Jim Ingham <[email protected]> (Mac),
			  Jeff Hobbs <[email protected]>

   27. ''dde Package'' - Kevin Kenny <[email protected]>
   1. ''Scan Command'' - 

   28. ''http Package'' - Jeff Hobbs <[email protected]>
   1. ''Channel Commands'' - 

   29. ''msgcat Package'' - 
   1. ''Channel System'' - 

   30. ''opt Package'' - 
   1. ''Channel Transforms'' - 

   31. ''registry Package'' - Kevin Kenny <[email protected]>
   1. ''Channel Types'' - 

   32. ''Safe Base'' - Jeff Hobbs <[email protected]>
   1. ''dde Package'' - 

   33. ''tcltest Package'' - Jeff Hobbs <[email protected]>,
	Melissa Chawla <[email protected]>
   1. ''http Package'' - 

   1. ''msgcat Package'' - 

   34. ''Pathname Management'' -
        Daniel Steffen <[email protected]> (Mac),
        Jim Ingham <[email protected]> (Mac),
	Vincent Darley <[email protected]>,
	Jeff Hobbs <[email protected]>
   1. ''opt Package'' - 

   1. ''registry Package'' - 

   1. ''Safe Base'' - 

   1. ''Tcltest'' - 

   1. ''Pathname Management'' - 

   35. ''File System'' - Daniel Steffen <[email protected]> (Mac),
   1. ''File System'' - 
                        Jim Ingham <[email protected]> (Mac),
			Vincent Darley <[email protected]>,
			Jeff Hobbs <[email protected]>

   36. ''Init - Library - Autoload'' -
   1. ''Init - Library - Autoload'' -
        Don Porter <[email protected]>,
        Daniel Steffen <[email protected]> (Mac),
        Jim Ingham <[email protected]> (Mac),
	Jeff Hobbs <[email protected]>

   37. ''Package Manager'' -  Don Porter <[email protected]>, Jeff Hobbs <[email protected]>
   1. ''Package Manager'' - 

   38. ''Dynamic Loading'' -  Kevin Kenny <[email protected]>,
   1. ''Dynamic Loading'' - 
                             Daniel Steffen <[email protected]> (Mac),
                             Jim Ingham <[email protected]> (Mac),
                             Jan Nijtmans <[email protected]>,
			     Jeff Hobbs <[email protected]>

   39. ''Memory Allocation'' - Jeff Hobbs <[email protected]>
   1. ''Memory Allocation'' - 

   40. ''Memory Preservation'' - Jeff Hobbs <[email protected]>

   41. ''Regexp'' -

   1. ''Memory Preservation'' - 

   1. ''Regexp'' -

   42. ''UTF-8 Strings'' - Jan Nijtmans <[email protected]>, Jeff Hobbs <[email protected]>
   1. ''UTF-8 Strings'' -

   43. ''Parsing and Eval'' - Miguel Sofer <[email protected]>, Jeff Hobbs <[email protected]>
   1. ''Parsing and Eval'' -

   44. ''Bytecode Compiler'' - Miguel Sofer <[email protected]>, Jeff Hobbs <[email protected]>
   1. ''Bytecodes'' -

   45. ''Threading'' - Andreas Kupries <[email protected]>,
   1. ''Threading'' -
                      Daniel Steffen <[email protected]> (Mac),
                      Jim Ingham <[email protected]> (Mac),
		      Jeff Hobbs <[email protected]>

   46. ''Embedding Support'' - Don Porter <[email protected]>,
   1. ''Embedding Support'' -
                              Daniel Steffen <[email protected]> (Mac),
                              Jim Ingham <[email protected]> (Mac),
			      Jeff Hobbs <[email protected]>

   47. ''Release Notes'' - Daniel Steffen <[email protected]> (Mac),
   1. ''Release Notes'' - 
                          Jim Ingham <[email protected]> (Mac),
			  Jeff Hobbs <[email protected]>

   48. ''Portability Support'' -
   1. ''Portability Support'' - 
        Mo DeJong <[email protected]>,
        Daniel Steffen <[email protected]> (Mac),
        Jim Ingham <[email protected]> (Mac),
	Jeff Hobbs <[email protected]>

   49. ''Configure and Build Tools'' - Mo DeJong <[email protected]>, Jeff Hobbs <[email protected]>,
   1. ''Configure and Build Tools'' - 
	Lloyd Lim <[email protected]>

   50. ''Other Tools'' - Jeff Hobbs <[email protected]>
   1. ''Other Tools'' - 

   51. ''[[resource]]'' - Daniel Steffen <[email protected]>
   1. ''resource Command'' - 
                      Jim Ingham <[email protected]>

   52. ''Macintosh'' - Daniel A. Steffen <[email protected]>,
   1. ''Macintosh'' -
                       Jim Ingham <[email protected]>

~ Orphaned Categories

The following Categories in Tcl's SourceForge Bug Tracker should be
mapped to new Categories corresponding to a maintained area of Tcl,
when seeking the appropriate maintainer:

   1. ''Build'' - map to ''Configure and Build Tools''.
   1. ''Other'' - Used for reports that span several categories.  Also
		  includes many closed old reports from before the time
		  the current categories were established.

   1. ''Clock'' - map to ''Time Measurement''.

   1. ''CodeCleanup'' - map to section of code being cleaned up.

   1. ''Commands'' - map to the specific command or one of ''A-H'',
      ''I-L'', or ''M-Z''.

   1. ''Docs'' - no longer a separate Category.  Map to the section
      of code being documented.

   1. ''Exec and Pipe'' - map to ''Channel Types''.

   1. ''File System (trash)'' - map to ''File System''.

   1. ''I18N'' - map to ???

   1. ''Installation'' - map to ''Configure and Build Tools''.

   1. ''Other'' - reassign once area is determined.

   1. ''Other IO'' - reassign to appropriate ''Channel'' category.

   1. ''Packaging'' - map to ???

   1. ''Sockets'' - map to ''Channel Types''.

   1. ''Tests'' - no longer a separate Category.  Map to the section
      of code being tested.

   1. ''Unix'' - map to specific problem on Unix.

   1. ''Windows'' - map to specific problem on Windows.

~ Sections Without Maintainers

Those sections without a maintainer are maintained by the Tcl Core
Team with each change requiring TYANNOTT review.

~ Copyright

This document has been placed in the public domain.
Deleted tip/26.patch.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537

































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff -c -r orig_2/tk8.4a2/doc/text.n try/tk8.4a2/doc/text.n
*** orig_2/tk8.4a2/doc/text.n	Fri Aug 25 08:58:33 2000
--- try/tk8.4a2/doc/text.n	Sat Jul  7 20:04:52 2001
***************
*** 26,31 ****
--- 26,34 ----
  \-highlightcolor	\-pady	\-yscrollcommand
  .SE
  .SH "WIDGET-SPECIFIC OPTIONS"
+ .OP \-autoseparators autoSseparators AutoSeparators
+ Specifies whether separators are automatically inserted in the undo
+ stack. Is only active when the \fB\-undo\fR option is true.
  .OP \-height height Height
  Specifies the desired height for the window, in units of characters
  in the font given by the \fB\-font\fR option.
***************
*** 83,88 ****
--- 86,94 ----
  If no \fB\-tabs\fR option is specified, or if it is specified as
  an empty list, then Tk uses default tabs spaced every eight
  (average size) characters.
+ .OP \-undo undo Undo
+ Specifies whether the undo mechanism is active (value \fB0\fR) or
+ not (value \fB1\fR).
  .OP \-width width Width
  Specifies the desired width for the window in units of characters
  in the font given by the \fB\-font\fR option.
***************
*** 141,146 ****
--- 147,155 ----
  widget.
  See EMBEDDED IMAGES below for more details.
  .VE
+ .PP
+ The text widget also has a built-in undo/redo mechanism. See 
+ UNDO MECHANISM below for more details.
  
  .SH INDICES
  .PP
***************
*** 682,687 ****
--- 691,699 ----
  If the selection is claimed away by another application or by another
  window within this application, then the \fBsel\fR tag will be removed
  from all characters in the text.
+ .IP [4]
+ Whenever the \fBsel\fR tag range changes a virtual event 
+ \fB<<Selection>>\fR is generated.
  .PP
  The \fBsel\fR tag is automatically defined when a text widget is
  created, and it may not be deleted with the ``\fIpathName \fBtag delete\fR''
***************
*** 702,707 ****
--- 714,760 ----
  cursor, and the insertion cursor will automatically be drawn at
  this point whenever the text widget has the input focus.
  
+ .SH "THE MODIFIED FLAG"
+ The text widget can keep track of changes to the content of the widget
+ by means of the modified flag. Inserting or deleting text will set
+ this flag. The flag can be queried, set and cleared programatically
+ as well. Whenever the flag changes state a \fB<<Modified>>\fR virtual 
+ event is generated. See the \fBedit modified\fR widget command for 
+ more details.
+ 
+ .SH "THE UNDO MECHANISM"
+ .PP
+ The text widget has an unlimited undo and redo mechanism. This undo 
+ mechanism is only active when the \fB-undo\fR widget option is true.
+ Every insert and delete action is recorded on this stack.
+ .PP
+ Boundaries are inserted between edit actions: the so-called 
+ separators. The purpose of these separators is to group inserts and
+ deletes into one compound edit action. When undoing a change everything
+ between two separators will be undone. The undone changes are then
+ moved to the redo stack, so that an undone edit can be redone again.
+ The redo stack is cleared whenever new edit actions are recorded
+ on the undo stack. The undo and redo stacks can be cleared to keep 
+ their depth under control.
+ .PP
+ Separators are inserted automatically when the 
+ \fB-autoseparators\fR widget option is true. You can insert separators
+ programatically as well. If a separator is already present at the top
+ of the undo stack no other will inserted. That means that two 
+ separators on the undo stack are always separated by at least one 
+ insert or delete action.
+ .PP
+ The undo mechanism is also linked to the modified flag. This means
+ that undoing or redoing changes can take a modified text widget back 
+ to the unmodified state or vice versa. The modified flag
+ will be set to automatically to the appropriate state. This 
+ automatic coupling does not work when the modified flag has been 
+ set by the user, until the flag has been reset again. 
+ 
+ .PP
+ See below for the \fBedit\fR widget command that controls the 
+ undo mechanism.
+ 
  .SH "WIDGET COMMAND"
  .PP
  The \fBtext\fR command creates a new Tcl command whose
***************
*** 863,868 ****
--- 916,956 ----
  window by its index position to get more information.
  .RE
  .TP
+ \fIpathName \fBedit \fIoption \fR?\fIarg arg ...\fR?
+ This command controls the undo mechanism and the modified flag.  
+ The exact behavior of the command depends on the \fIoption\fR 
+ argument that follows the \fBedit\fR argument.  The following 
+ forms of the command are currently supported:
+ .RS
+ .TP
+ \fIpathName \fBedit modified ?\fIboolean\fR?
+ If \fIboolean\fR is not specified, returns the modified flag of
+ the widget. The insert, delete, edit undo and edit redo commands
+ or the user can set or clear the modified flag.
+ If \fIboolean\fR is specified, sets the modified flag of the widget
+ to \fIboolean\fR.
+ .TP
+ \fIpathName \fBedit redo\fR
+ When the \fB-undo\fR option is true, reapplies the last undone 
+ edits provided no other edits were done since then. Generates an
+ error when the redo stack is empty.
+ Does nothing when the \fB-undo\fR option is false.
+ .TP
+ \fIpathName \fBedit reset\fR
+ Clears the undo and redo stacks.
+ .TP
+ \fIpathName \fBedit separator\fR
+ Inserts a separator (boundary) on the undo stack. Does nothing
+ when the \fB-undo\fR option is false.
+ .TP
+ \fIpathName \fBedit undo\fR
+ Undoes the last edit action when the \fB-undo\fR option is true. 
+ An edit action is defined as all the insert and delete commands that are 
+ recorded on the undo stack in between two separators. Generates an error
+ when the undo stack is empty.
+ Does nothing when the \fB-undo\fR option is false.
+ .RE
+ .TP
  \fIpathName \fBget \fIindex1 \fR?\fIindex2\fR?
  Return a range of characters from the text.
  The return value will be all the characters in the text starting
***************
*** 1591,1596 ****
--- 1679,1690 ----
  .IP [31]
  Control-t reverses the order of the two characters to the right of
  the insertion cursor. 
+ .IP [32]
+ Control-z undoes the last edit action if the \fB-undo\fR option is
+ true. Does nothing otherwise.
+ .IP [33]
+ Control-Z reapplies the last undone edit action if the \fB-undo\fR 
+ option is true. Does nothing otherwise.
  .PP
  If the widget is disabled using the \fB\-state\fR option, then its
  view can still be adjusted and text can still be selected,
diff -c -r orig_2/tk8.4a2/generic/tkText.c try/tk8.4a2/generic/tkText.c
*** orig_2/tk8.4a2/generic/tkText.c	Tue Jul 25 02:05:40 2000
--- try/tk8.4a2/generic/tkText.c	Sun Jul  8 07:48:11 2001
***************
*** 42,47 ****
--- 42,50 ----
   */
  
  static Tk_ConfigSpec configSpecs[] = {
+     {TK_CONFIG_BOOLEAN, "-autoseparators", "autoSeparators",
+         "AutoSeparators", DEF_TEXT_AUTO_SEPARATORS,
+         Tk_Offset(TkText, autoSeparators), 0},
      {TK_CONFIG_BORDER, "-background", "background", "Background",
  	DEF_TEXT_BG_COLOR, Tk_Offset(TkText, border), TK_CONFIG_COLOR_ONLY},
      {TK_CONFIG_BORDER, "-background", "background", "Background",
***************
*** 129,134 ****
--- 132,139 ----
      {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus",
  	DEF_TEXT_TAKE_FOCUS, Tk_Offset(TkText, takeFocus),
  	TK_CONFIG_NULL_OK},
+     {TK_CONFIG_BOOLEAN, "-undo", "undo", "Undo",
+         DEF_TEXT_UNDO, Tk_Offset(TkText, undo), 0},
      {TK_CONFIG_INT, "-width", "width", "Width",
  	DEF_TEXT_WIDTH, Tk_Offset(TkText, width), 0},
      {TK_CONFIG_CUSTOM, "-wrap", "wrap", "Wrap",
***************
*** 292,297 ****
--- 297,304 ----
  			    int offset, char *buffer, int maxBytes));
  static int		TextSearchCmd _ANSI_ARGS_((TkText *textPtr,
  			    Tcl_Interp *interp, int argc, char **argv));
+ static int              TextEditCmd _ANSI_ARGS_((TkText *textPtr,
+                             Tcl_Interp *interp, int argc, char **argv));
  static int		TextWidgetCmd _ANSI_ARGS_((ClientData clientData,
  			    Tcl_Interp *interp, int argc, char **argv));
  static void		TextWorldChanged _ANSI_ARGS_((
***************
*** 304,309 ****
--- 311,336 ----
  static int		DumpSegment _ANSI_ARGS_((Tcl_Interp *interp, char *key,
  			    char *value, char * command, TkTextIndex *index,
  			    int what));
+ static int              TextEditUndo _ANSI_ARGS_((Tcl_Interp * interp,
+                             TkText *textPtr));
+ static int              TextEditRedo _ANSI_ARGS_((Tcl_Interp * interp,
+                             TkText *textPtr));
+ static char *           TextGetText _ANSI_ARGS_((TkTextIndex * index1,
+                             TkTextIndex * index2));
+ static void             pushStack _ANSI_ARGS_(( TkTextEditAtom ** stack, 
+                             TkTextEditAtom * elem ));
+ 
+ static TkTextEditAtom * popStack   _ANSI_ARGS_(( TkTextEditAtom ** stack ));
+ 
+ static void             clearStack _ANSI_ARGS_(( TkTextEditAtom ** stack ));
+ 
+ static void             insertSeparator _ANSI_ARGS_(( TkTextEditAtom ** stack ));
+ 
+ static void             updateDirtyFlag _ANSI_ARGS_((TkText *textPtr));
+ 
+ static void             setDirtyFlag  _ANSI_ARGS_((TkText *textPtr));
+ 
+ static void             resetDirtyFlag  _ANSI_ARGS_((TkText *textPtr));
  
  /*
   * The structure below defines text class behavior by means of procedures
***************
*** 426,431 ****
--- 453,465 ----
      textPtr->xScrollCmd = NULL;
      textPtr->yScrollCmd = NULL;
      textPtr->flags = 0;
+     textPtr->undo = 1;
+     textPtr->modifiedSet = 0;
+     textPtr->isDirty = 0;
+     textPtr->isDirtyIncrement = 1;
+     textPtr->undoStack = NULL;
+     textPtr->redoStack = NULL;
+     textPtr->autoSeparators = 1;
  
      /*
       * Create the "sel" tag and the "current" and "insert" marks.
***************
*** 489,494 ****
--- 523,529 ----
      size_t length;
      int c;
      TkTextIndex index1, index2;
+     char * string;
  
      if (argc < 2) {
  	Tcl_AppendResult(interp, "wrong # args: should be \"",
***************
*** 636,641 ****
--- 671,678 ----
  	    sprintf(buf, "%d %d %d %d %d", x, y, width, height, base);
  	    Tcl_SetResult(interp, buf, TCL_VOLATILE);
  	}
+     } else if ((c == 'e') && (strncmp(argv[1], "edit", length) == 0)) {
+         result = TextEditCmd(textPtr, interp, argc, argv);
      } else if ((c == 'g') && (strncmp(argv[1], "get", length) == 0)) {
  	if ((argc != 3) && (argc != 4)) {
  	    Tcl_AppendResult(interp, "wrong # args: should be \"",
***************
*** 658,689 ****
  	if (TkTextIndexCmp(&index1, &index2) >= 0) {
  	    goto done;
  	}
! 	while (1) {
! 	    int offset, last, savedChar;
! 	    TkTextSegment *segPtr;
! 
! 	    segPtr = TkTextIndexToSeg(&index1, &offset);
! 	    last = segPtr->size;
! 	    if (index1.linePtr == index2.linePtr) {
! 		int last2;
! 
! 		if (index2.byteIndex == index1.byteIndex) {
! 		    break;
! 		}
! 		last2 = index2.byteIndex - index1.byteIndex + offset;
! 		if (last2 < last) {
! 		    last = last2;
! 		}
! 	    }
! 	    if (segPtr->typePtr == &tkTextCharType) {
! 		savedChar = segPtr->body.chars[last];
! 		segPtr->body.chars[last] = 0;
! 		Tcl_AppendResult(interp, segPtr->body.chars + offset,
! 			(char *) NULL);
! 		segPtr->body.chars[last] = savedChar;
! 	    }
! 	    TkTextIndexForwBytes(&index1, last-offset, &index1);
! 	}
      } else if ((c == 'i') && (strncmp(argv[1], "index", length) == 0)
  	    && (length >= 3)) {
  	char buf[200];
--- 695,704 ----
  	if (TkTextIndexCmp(&index1, &index2) >= 0) {
  	    goto done;
  	}
!         string = TextGetText(&index1,&index2);
!         Tcl_AppendResult(interp, string, (char *) NULL);
!         ckfree(string);
!         
      } else if ((c == 'i') && (strncmp(argv[1], "index", length) == 0)
  	    && (length >= 3)) {
  	char buf[200];
***************
*** 771,778 ****
      } else {
  	Tcl_AppendResult(interp, "bad option \"", argv[1],
  		"\": must be bbox, cget, compare, configure, debug, delete, ",
! 		"dlineinfo, dump, get, image, index, insert, mark, scan, ",
! 		"search, see, tag, window, xview, or yview",
  		(char *) NULL);
  	result = TCL_ERROR;
      }
--- 786,793 ----
      } else {
  	Tcl_AppendResult(interp, "bad option \"", argv[1],
  		"\": must be bbox, cget, compare, configure, debug, delete, ",
!                 "dlineinfo, dump, edit, get, image, index, insert, mark, ",
!                 "scan, search, see, tag, window, xview, or yview",
  		(char *) NULL);
  	result = TCL_ERROR;
      }
***************
*** 1209,1214 ****
--- 1224,1232 ----
  {
      int lineIndex, resetView, offset;
      TkTextIndex newTop;
+     TkTextEditAtom * insertion;
+     char indexBuffer[TK_POS_CHARS];
+     
  
      /*
       * Don't allow insertions on the last (dummy) line of the text.
***************
*** 1237,1242 ****
--- 1255,1286 ----
      }
      TkTextChanged(textPtr, indexPtr, indexPtr);
      TkBTreeInsertChars(indexPtr, string);
+ 
+     /*
+      * Push the insertion on the undo stack
+      */
+ 
+     if ( textPtr->undo ) {
+         if (textPtr->autoSeparators && textPtr->undoStack &&
+             textPtr->undoStack->type != INSERT) {
+             insertSeparator(&(textPtr->undoStack));
+         }
+         
+         insertion = (TkTextEditAtom *) ckalloc(sizeof(TkTextEditAtom));
+         insertion->type = INSERT;
+         
+         TkTextPrintIndex(indexPtr,indexBuffer);
+         insertion->index = (char *) ckalloc(strlen(indexBuffer) + 1);
+         strcpy(insertion->index,indexBuffer);
+         
+         insertion->string = (char *) ckalloc(strlen(string) + 1);
+         strcpy(insertion->string,string);
+ 
+         pushStack(&(textPtr->undoStack),insertion);
+         clearStack(&(textPtr->redoStack));
+     }
+     updateDirtyFlag(textPtr);
+ 
      if (resetView) {
  	TkTextMakeByteIndex(textPtr->tree, lineIndex, 0, &newTop);
  	TkTextIndexForwBytes(&newTop, offset, &newTop);
***************
*** 1280,1285 ****
--- 1324,1331 ----
  {
      int line1, line2, line, byteIndex, resetView;
      TkTextIndex index1, index2;
+     TkTextEditAtom * deletion;
+     char indexBuffer[TK_POS_CHARS];
  
      /*
       * Parse the starting and stopping indices.
***************
*** 1391,1396 ****
--- 1437,1467 ----
  	    byteIndex -= (index2.byteIndex - index1.byteIndex);
  	}
      }
+     
+     
+     /*
+      * Push the deletion on the undo stack
+      */
+ 
+     if ( textPtr->undo ) {
+         if (textPtr->autoSeparators && textPtr->undoStack && textPtr->undoStack->type != DELETE) {
+            insertSeparator(&(textPtr->undoStack));
+         }
+         
+         deletion = (TkTextEditAtom *) ckalloc(sizeof(TkTextEditAtom));
+         deletion->type = DELETE;
+         
+         TkTextPrintIndex(&index1,indexBuffer);
+         deletion->index = (char *) ckalloc(strlen(indexBuffer) + 1);
+         strcpy(deletion->index,indexBuffer);
+         
+         deletion->string = TextGetText(&index1, &index2);
+ 
+         pushStack(&(textPtr->undoStack),deletion);
+         clearStack(&(textPtr->redoStack));
+     }
+     updateDirtyFlag(textPtr);
+ 
      TkBTreeDeleteChars(&index1, &index2);
      if (resetView) {
  	TkTextMakeByteIndex(textPtr->tree, line, byteIndex, &index1);
***************
*** 1572,1577 ****
--- 1643,1649 ----
      register TkText *textPtr = (TkText *) clientData;
  #ifdef ALWAYS_SHOW_SELECTION
      TkTextIndex start, end;
+     char selMessage[1000];
  
      if (!textPtr->exportSelection) {
  	return;
***************
*** 1588,1593 ****
--- 1660,1668 ----
      TkTextRedrawTag(textPtr, &start, &end, textPtr->selTagPtr, 1);
      TkBTreeTag(&start, &end, textPtr->selTagPtr, 0);
  #endif
+     /* Send an event that the selection changed */
+     sprintf(selMessage,"event generate %s <<Selection>>",Tk_PathName(textPtr->tkwin));
+     Tcl_Eval(textPtr->interp,selMessage);
      textPtr->flags &= ~GOT_SELECTION;
  }
  
***************
*** 2421,2423 ****
--- 2496,2990 ----
      }
  }
  
+ 
+ /*
+  * pushStack
+  *    Push elem on the stack identified by stack.
+  *
+  * Results:
+  *    None
+  *
+  * Side effects:
+  *    None.
+  */
+  
+ static void pushStack ( stack, elem )
+     TkTextEditAtom ** stack;
+     TkTextEditAtom *  elem;
+ { 
+     elem->next = *stack;
+     *stack = elem;
+ }
+ 
+ 
+ /*
+  * popStack --
+  *    Remove and return the top element from the stack identified by 
+  *      stack.
+  *
+  * Results:
+  *    None
+  *
+  * Side effects:
+  *    None.
+  */
+  
+ TkTextEditAtom * popStack ( stack )
+     TkTextEditAtom ** stack ;
+ { 
+     TkTextEditAtom * elem = NULL;
+     if (*stack != NULL ) {
+         elem   = *stack;
+         *stack = elem->next;
+     }
+     return elem;
+ }
+ 
+ 
+ /*
+  * insertSeparator --
+  *    insert a separator on the stack, indicating a border for
+  *      an undo/redo chunk.
+  *
+  * Results:
+  *    None
+  *
+  * Side effects:
+  *    None.
+  */
+  
+ static void insertSeparator ( stack )
+     TkTextEditAtom ** stack;
+ {
+     TkTextEditAtom * separator;
+ 
+     if ( *stack != NULL && (*stack)->type != SEPARATOR ) {
+         separator = (TkTextEditAtom *) ckalloc(sizeof(TkTextEditAtom));
+         separator->type = SEPARATOR;
+         pushStack(stack,separator);
+     }
+ }
+ 
+ 
+ /*
+  * clearStack --
+  *    Clear an entire undo or redo stack and destroy all elements in it.
+  *
+  * Results:
+  *    None
+  *
+  * Side effects:
+  *    None.
+  */
+  
+ static void clearStack ( stack )
+     TkTextEditAtom ** stack;      /* An Undo or Redo stack */
+ {
+     TkTextEditAtom * elem;
+ 
+     while ( (elem = popStack(stack)) ) {
+         if ( elem->type != SEPARATOR ) {
+             ckfree(elem->index);
+             ckfree(elem->string);
+         }
+         ckfree((char *)elem);
+     }
+     *stack = NULL;
+ }
+ 
+ 
+ /*
+  * TextEditUndo --
+  *    undo the last change.
+  *
+  * Results:
+  *    None
+  *
+  * Side effects:
+  *    None.
+  */
+  
+ static int TextEditUndo (interp,textPtr)
+     Tcl_Interp * interp;
+     TkText     * textPtr;             /* Overall information about text widget. */
+ {
+     TkTextEditAtom * elem      ;
+     TkTextIndex      fromIndex ;
+     TkTextIndex      toIndex   ;
+     char             buffer[TK_POS_CHARS];
+     char             viewIndex[TK_POS_CHARS];
+     
+     if ( ! textPtr->undo ) {
+        return TCL_OK;
+     }
+     
+ 
+     /* Turn off the undo feature */
+     
+     textPtr->undo = 0;
+     
+     /* insert a separator on the redo stack */
+     
+     insertSeparator(&(textPtr->redoStack));
+     
+     /* Pop and skip the first separator if there is one*/
+     
+     elem = popStack(&(textPtr->undoStack));
+ 
+     if ( elem == NULL ) {
+         textPtr->undo = 1;
+         return TCL_ERROR;
+     }
+     
+     if ( ( elem != NULL ) && ( elem->type == SEPARATOR ) ) {
+         ckfree((char *) elem);
+         elem = popStack(&(textPtr->undoStack));
+     }
+     
+     while ( elem && (elem->type != SEPARATOR) ) {
+         switch ( elem->type ) {
+             case INSERT:
+                 TkTextGetIndex(interp,textPtr,elem->index,&toIndex);
+                 strcpy(viewIndex,elem->index);
+                 TkTextIndexForwBytes(&toIndex,(int)strlen(elem->string),&toIndex);
+                 TkTextPrintIndex(&toIndex,buffer);
+                 textPtr->isDirtyIncrement = -1;
+                 DeleteChars(textPtr,elem->index,buffer);
+                 textPtr->isDirtyIncrement = 1;
+                 break;
+             case DELETE: 
+                 TkTextGetIndex(interp,textPtr,elem->index,&fromIndex);
+                 textPtr->isDirtyIncrement = -1;
+                 InsertChars(textPtr,&fromIndex,elem->string);
+                 TkTextIndexForwBytes(&fromIndex,(int)strlen(elem->string),&toIndex);
+                 TkTextPrintIndex(&toIndex,viewIndex);
+                 textPtr->isDirtyIncrement = 1;
+                 break;
+             default:
+                 return TCL_ERROR;
+         }
+         pushStack(&(textPtr->redoStack),elem);
+         elem = popStack(&(textPtr->undoStack));
+     }
+     
+     /* view the last changed position */
+     
+     TkTextGetIndex(interp,textPtr,viewIndex,&toIndex);
+     TkTextSetMark(textPtr, "insert", &toIndex);
+ 
+     /* insert a separator on the undo stack */
+     
+     insertSeparator(&(textPtr->undoStack));
+     
+     /* Turn back on the undo feature */
+     
+     textPtr->undo = 1;
+     
+     return TCL_OK;
+ }
+ 
+ 
+ /*
+  * TextEditRedo --
+  *    redo the last undone change.
+  *
+  * Results:
+  *    None
+  *
+  * Side effects:
+  *    None.
+  */
+  
+ static int TextEditRedo (interp,textPtr)
+     Tcl_Interp * interp;
+     TkText     * textPtr;             /* Overall information about text widget. */
+ {
+     TkTextEditAtom * elem      ;
+     TkTextIndex      fromIndex ;
+     TkTextIndex      toIndex   ;
+     char             buffer[TK_POS_CHARS];
+     char             viewIndex[TK_POS_CHARS];
+     
+     if ( ! textPtr->undo ) {
+        return TCL_OK;
+     }
+     
+     /* Turn off the undo feature temporarily */
+     
+     textPtr->undo = 0;
+     
+     /* insert a separator on the undo stack */
+     
+     insertSeparator(&(textPtr->undoStack));
+     
+     /* Pop and skip the first separator if there is one*/
+     
+     elem = popStack(&(textPtr->redoStack));
+ 
+     if ( elem == NULL ) {
+        textPtr->undo = 1;
+        return TCL_ERROR;
+     }
+     
+     if ( ( elem != NULL ) && ( elem->type == SEPARATOR ) ) {
+         ckfree((char *) elem);
+         elem = popStack(&(textPtr->redoStack));
+     }
+     
+     while ( elem && (elem->type != SEPARATOR) ) {
+         switch ( elem->type ) {
+             case INSERT:
+                 TkTextGetIndex(interp,textPtr,elem->index,&fromIndex);
+                 InsertChars(textPtr,&fromIndex,elem->string);
+                 TkTextIndexForwBytes(&fromIndex,(int)strlen(elem->string),&toIndex);
+                 TkTextPrintIndex(&toIndex,viewIndex);
+                 break;
+             case DELETE: 
+                 TkTextGetIndex(interp,textPtr,elem->index,&toIndex);
+                 strcpy(viewIndex,elem->index);
+                 TkTextIndexForwBytes(&toIndex,(int)strlen(elem->string),&toIndex);
+                 TkTextPrintIndex(&toIndex,buffer);
+                 DeleteChars(textPtr,elem->index,buffer);
+                 break;
+             default:
+                 return TCL_ERROR;
+         }
+         pushStack(&(textPtr->undoStack),elem);
+         elem = popStack(&(textPtr->redoStack));
+     }
+     
+     /* view the last changed position */
+     
+     TkTextGetIndex(interp,textPtr,viewIndex,&toIndex);
+     TkTextSetMark(textPtr, "insert", &toIndex);
+ 
+     /* insert a separator on the undo stack */
+     
+     insertSeparator(&(textPtr->undoStack));
+ 
+     /* Turn back on the undo feature */
+     
+     textPtr->undo = 1;
+     
+     return TCL_OK;
+ }
+ 
+ static int
+ TextEditCmd(textPtr, interp, argc, argv)
+     TkText *textPtr;          /* Information about text widget. */
+     Tcl_Interp *interp;               /* Current interpreter. */
+     int argc;                 /* Number of arguments. */
+     char **argv;              /* Argument strings. */
+ {
+     int      c            ;
+     size_t   length       ;
+     int      setModified  ;
+     
+     if (argc < 3) {
+       Tcl_AppendResult(interp, "wrong # args: should be \"",
+               argv[0], " edit option ?arg arg ...?\"", (char *) NULL);
+       return TCL_ERROR;
+     }
+     c = argv[2][0];
+     length = strlen(argv[2]);
+     if ((c == 'm') && (strncmp(argv[2], "modified", length) == 0)) {
+       if (argc != 3) {
+ 	    if (Tcl_GetBoolean(interp, argv[3], &setModified) == TCL_OK) {
+                 if ( argc != 4 ) {
+                   Tcl_AppendResult(interp, "wrong # args: should be \"",
+                           argv[0], " edit modified ?boolean? \"", (char *) NULL);
+                   return TCL_ERROR;
+                 }
+                 if ( setModified ) {
+                     setDirtyFlag(textPtr);
+                 } else {
+                     resetDirtyFlag(textPtr);
+                 }
+             } else {
+               Tcl_AppendResult(interp, "bad modified option \"", argv[3],
+                       "\": must be a boolean",
+                       (char *) NULL);
+               return TCL_ERROR;
+             }
+       } else {
+             if (textPtr->isDirty) {
+                 Tcl_AppendResult(interp, "1",(char *) NULL);
+             } else {
+                 Tcl_AppendResult(interp, "0",(char *) NULL);
+             }
+         }
+     } else if ((c == 'r') && (strncmp(argv[2], "redo", length) == 0)  && (length >= 3)) {
+       if (argc != 3) {
+           Tcl_AppendResult(interp, "wrong # args: should be \"",
+                   argv[0], " edit redo \"", (char *) NULL);
+           return TCL_ERROR;
+       }
+         if ( TextEditRedo(interp,textPtr) ) {
+             Tcl_AppendResult(interp, "nothing to redo",
+                   (char *) NULL);
+           return TCL_ERROR;
+         }
+     } else if ((c == 'r') && (strncmp(argv[2], "reset", length) == 0) && (length >= 3)) {
+       if (argc != 3) {
+           Tcl_AppendResult(interp, "wrong # args: should be \"",
+                   argv[0], " edit reset \"", (char *) NULL);
+           return TCL_ERROR;
+       }
+         clearStack(&(textPtr->undoStack));
+         clearStack(&(textPtr->redoStack));
+     } else if ((c == 's') && (strncmp(argv[2], "separator", length) == 0)) {
+       if (argc != 3) {
+           Tcl_AppendResult(interp, "wrong # args: should be \"",
+                   argv[0], " edit separator \"", (char *) NULL);
+           return TCL_ERROR;
+       }
+         insertSeparator(&(textPtr->undoStack));
+     } else if ((c == 'u') && (strncmp(argv[2], "undo", length) == 0)) {
+       if (argc != 3) {
+           Tcl_AppendResult(interp, "wrong # args: should be \"",
+                   argv[0], " edit undo \"", (char *) NULL);
+           return TCL_ERROR;
+       }
+         if ( TextEditUndo(interp,textPtr) ) {
+             Tcl_AppendResult(interp, "nothing to undo",
+                   (char *) NULL);
+           return TCL_ERROR;
+         }
+     } else {
+       Tcl_AppendResult(interp, "bad edit option \"", argv[2],
+               "\": must be modified, redo, reset, separator or undo",
+               (char *) NULL);
+       return TCL_ERROR;
+     }
+     
+     return TCL_OK;
+ }
+ 
+ 
+ 
+ /*
+  * TextGetText --
+  *    returns the text from indexPtr1 to indexPtr2.
+  *
+  * Results:
+  *    the string between indices indexPtr1 and indexPtr2
+  *
+  * Side effects:
+  *    None.
+  */
+  
+ char * TextGetText(indexPtr1,indexPtr2)
+     TkTextIndex * indexPtr1;
+     TkTextIndex * indexPtr2;
+ {
+     TkTextIndex tmpIndex;
+     char * string;
+     string = (char *) ckalloc(1);
+     *string = '\0';
+     
+     TkTextMakeByteIndex(indexPtr1->tree,TkBTreeLineIndex(indexPtr1->linePtr),indexPtr1->byteIndex,&tmpIndex);
+ 
+     if (TkTextIndexCmp(indexPtr1, indexPtr2) >= 0) {
+       return string;
+     }
+     while (1) {
+       int offset, last, savedChar;
+       TkTextSegment *segPtr;
+ 
+       segPtr = TkTextIndexToSeg(&tmpIndex, &offset);
+       last = segPtr->size;
+       if (tmpIndex.linePtr == indexPtr2->linePtr) {
+           int last2;
+ 
+           if (indexPtr2->byteIndex == tmpIndex.byteIndex) {
+               break;
+           }
+           last2 = indexPtr2->byteIndex - tmpIndex.byteIndex + offset;
+           if (last2 < last) {
+               last = last2;
+           }
+       }
+       if (segPtr->typePtr == &tkTextCharType) {
+           savedChar = segPtr->body.chars[last];
+           segPtr->body.chars[last] = 0;
+             string = (char *) ckrealloc(string,strlen(string) + strlen(segPtr->body.chars + offset) + 1);
+             strcat(string,segPtr->body.chars + offset);
+           segPtr->body.chars[last] = savedChar;
+       }
+       TkTextIndexForwBytes(&tmpIndex, last-offset, &tmpIndex);
+     }
+ 
+     return string;
+ }
+ 
+ 
+ /*
+  * updateDirtyFlag --
+  *    increases the dirtyness of the text widget
+  *
+  * Results:
+  *    None
+  *
+  * Side effects:
+  *    None.
+  */
+  
+ static void updateDirtyFlag (textPtr)
+     TkText *textPtr;          /* Information about text widget. */
+ {
+     char eventMessage[1000];
+     int oldDirtyFlag;
+ 
+     if ( textPtr->modifiedSet ) {
+         return;
+     }
+     oldDirtyFlag = textPtr->isDirty;
+     textPtr->isDirty += textPtr->isDirtyIncrement;
+     if (textPtr->isDirty == 0 || oldDirtyFlag == 0) {
+         sprintf(eventMessage,"event generate %s <<Modified>>",Tk_PathName(textPtr->tkwin));
+         Tcl_Eval(textPtr->interp,eventMessage);
+     }
+ }
+ 
+ /*
+  * setDirtyFlag --
+  *    sets the dirtyness of the text widget
+  *
+  * Results:
+  *    None
+  *
+  * Side effects:
+  *    None.
+  */
+  
+ static void setDirtyFlag (textPtr)
+     TkText *textPtr;          /* Information about text widget. */
+ {
+     char eventMessage[1000];
+     textPtr->isDirty = 1;
+     textPtr->modifiedSet = 1;
+     sprintf(eventMessage,"event generate %s <<Modified>>",Tk_PathName(textPtr->tkwin));
+     Tcl_Eval(textPtr->interp,eventMessage);
+ }
+   
+ /*
+  * resetDirtyFlag --
+  *    resets the dirtyness of the text widget
+  *
+  * Results:
+  *    None
+  *
+  * Side effects:
+  *    None.
+  */
+  
+ static void resetDirtyFlag (textPtr)
+     TkText *textPtr;          /* Information about text widget. */
+ {
+     char eventMessage[1000];
+     textPtr->isDirty = 0;
+     textPtr->modifiedSet = 0;
+     sprintf(eventMessage,"event generate %s <<Modified>>",Tk_PathName(textPtr->tkwin));
+     Tcl_Eval(textPtr->interp,eventMessage);
+ }
+   
diff -c -r orig_2/tk8.4a2/generic/tkText.h try/tk8.4a2/generic/tkText.h
*** orig_2/tk8.4a2/generic/tkText.h	Thu Jan  6 03:18:58 2000
--- try/tk8.4a2/generic/tkText.h	Sat Jul  7 19:35:34 2001
***************
*** 451,456 ****
--- 451,473 ----
  					 * BE THE LAST IN THE STRUCTURE. */
  } TkTextTabArray;
  
+ /* enum definining the types used in an edit stack */
+ 
+ typedef enum {
+     SEPARATOR,                          /* Marker */
+     INSERT,                             /* The undo is an insert */
+     DELETE                              /* The undo is a delete */
+ } TkTextEditType;
+ 
+ /* strcut defining the basic undo/redo stack element */
+ 
+ typedef struct TkTextEditAtom {
+     TkTextEditType type;                /* The type that will trigger the required action*/
+     char * index;                       /* The starting index of the range */
+     char * string;                      /* The text to be inserted or deleted */
+     struct TkTextEditAtom * next;       /* Pointer to the next element in the stack */
+ } TkTextEditAtom;
+ 
  /*
   * A data structure of the following type is kept for each text widget that
   * currently exists for this process:
***************
*** 625,630 ****
--- 642,675 ----
  				 * vertical scrollbar when view changes. */
      int flags;			/* Miscellaneous flags;  see below for
  				 * definitions. */
+ 
+     /*
+      * Information related to the undo/redo functonality
+      */
+      
+     TkTextEditAtom * undoStack; /* The undo stack */
+     
+     TkTextEditAtom * redoStack; /* The redo stack */
+     
+     int undo;                   /* non zero means the undo/redo behaviour is 
+                                  * enabled */
+     
+     int autoSeparators;         /* non zero means the separatorss will be 
+                                  * inserted automatically */
+     
+     int modifiedSet;            /* Flag indicating that the 'dirtynesss' of
+                                  * the text widget has been expplicitly set.
+                                  */
+ 
+     int isDirty;                /* Flag indicating the 'dirtynesss' of the text
+                                  * widget. If the flag is not zero, unsaved 
+                                  * modifications have been applied to the
+                                  * text widget */
+ 
+     int isDirtyIncrement;       /* Amount with which the isDirty flag is
+                                  * incremented every edit action
+                                  */
+ 
  } TkText;
  
  /*
diff -c -r orig_2/tk8.4a2/generic/tkTextTag.c try/tk8.4a2/generic/tkTextTag.c
*** orig_2/tk8.4a2/generic/tkTextTag.c	Thu Jan  6 03:18:59 2000
--- try/tk8.4a2/generic/tkTextTag.c	Sat Feb 17 11:27:04 2001
***************
*** 114,119 ****
--- 114,120 ----
      char *fullOption;
      register TkTextTag *tagPtr;
      TkTextIndex first, last, index1, index2;
+     char selMessage[1000];
  
      if (argc < 3) {
  	Tcl_AppendResult(interp, "wrong # args: should be \"",
***************
*** 171,176 ****
--- 172,180 ----
  	     */
      
  	    if (tagPtr == textPtr->selTagPtr) {
+                 /* Send an event that the selection changed */
+                 sprintf(selMessage,"event generate %s <<Selection>>",Tk_PathName(textPtr->tkwin));
+                 Tcl_Eval(textPtr->interp,selMessage);
  		if (addTag && textPtr->exportSelection
  			&& !(textPtr->flags & GOT_SELECTION)) {
  		    Tk_OwnSelection(textPtr->tkwin, XA_PRIMARY,
***************
*** 462,467 ****
--- 466,478 ----
  	    TkTextMakeByteIndex(textPtr->tree, TkBTreeNumLines(textPtr->tree),
  		    0, &last),
  	    TkBTreeTag(&first, &last, tagPtr, 0);
+ 
+             if (tagPtr == textPtr->selTagPtr) {
+                 /* Send an event that the selection changed */
+                 sprintf(selMessage,"event generate %s <<Selection>>",Tk_PathName(textPtr->tkwin));
+                 Tcl_Eval(textPtr->interp,selMessage);
+             }
+ 
  	    Tcl_DeleteHashEntry(hPtr);
  	    if (textPtr->bindingTable != NULL) {
  		Tk_DeleteAllBindings(textPtr->bindingTable,
diff -c -r orig_2/tk8.4a2/library/text.tcl try/tk8.4a2/library/text.tcl
*** orig_2/tk8.4a2/library/text.tcl	Thu Jul 20 01:22:20 2000
--- try/tk8.4a2/library/text.tcl	Sun Jul  8 07:26:00 2001
***************
*** 204,209 ****
--- 204,210 ----
  }
  bind Text <Return> {
      tkTextInsert %W \n
+     if {[%W cget -autoseparators]} {%W edit separator}
  }
  bind Text <Delete> {
      if {[string compare [%W tag nextrange sel 1.0 end] ""]} {
***************
*** 338,343 ****
--- 339,356 ----
      }
  }
  
+ bind Text <<Undo>> {
+     if { ! [ catch { %W edit undo } ] } {
+        %W see insert
+     }
+ }
+ 
+ bind Text <<Redo>> {
+     if { ! [ catch { %W edit redo } ] } {
+        %W see insert
+     }
+ }
+ 
  if {[string compare $tcl_platform(platform) "windows"]} {
  bind Text <Control-v> {
      if {!$tk_strictMotif} {
***************
*** 518,523 ****
--- 531,537 ----
      $w mark set insert [tkTextClosestGap $w $x $y]
      $w mark set anchor insert
      if {[string equal [$w cget -state] "normal"]} {focus $w}
+     if {[$w cget -autoseparators]} {$w edit separator}
  }
  
  # tkTextSelectTo --
***************
*** 633,639 ****
  
  proc tkTextPaste {w x y} {
      $w mark set insert [tkTextClosestGap $w $x $y]
!     catch {$w insert insert [selection get -displayof $w]}
      if {[string equal [$w cget -state] "normal"]} {focus $w}
  }
  
--- 647,664 ----
  
  proc tkTextPaste {w x y} {
      $w mark set insert [tkTextClosestGap $w $x $y]
!     catch {
!         set oldSeparator [$w cget -autoseparators]
!         if {$oldSeparator} {
!             $w configure -autoseparators 0
!             $w edit separator
!         }
!         $w insert insert [selection get -displayof $w]
!         if {$oldSeparator} {
!            $w edit separator
!            $w configure -autoseparators 1
!         }
!     }
      if {[string equal [$w cget -state] "normal"]} {focus $w}
  }
  
***************
*** 685,690 ****
--- 710,716 ----
      $w mark set insert $pos
      $w tag remove sel 1.0 end
      $w see insert
+     if {[$w cget -autoseparators]} {$w edit separator}
  }
  
  # tkTextKeySelect
***************
*** 794,807 ****
--- 820,844 ----
      if {[string equal $s ""] || [string equal [$w cget -state] "disabled"]} {
  	return
      }
+     set compound 0
      catch {
  	if {[$w compare sel.first <= insert] \
  		&& [$w compare sel.last >= insert]} {
+             set oldSeparator [$w cget -autoseparators]
+             if { $oldSeparator } {
+                 $w configure -autoseparators 0
+                 $w edit separator
+                 set compound 1
+             }
  	    $w delete sel.first sel.last
  	}
      }
      $w insert insert $s
      $w see insert
+     if { $compound && $oldSeparator } {
+         $w edit separator
+         $w configure -autoseparators 1
+     }
  }
  
  # tkTextUpDownLine --
***************
*** 975,986 ****
--- 1012,1032 ----
  proc tk_textPaste w {
      global tcl_platform
      catch {
+         set oldSeparator [$w cget -autoseparators]
+         if { $oldSeparator } {
+             $w configure -autoseparators 0
+             $w edit separator
+         }
  	if {[string compare $tcl_platform(platform) "unix"]} {
  	    catch {
  		$w delete sel.first sel.last
  	    }
  	}
  	$w insert insert [selection get -displayof $w -selection CLIPBOARD]
+         if { $oldSeparator } {
+             $w edit separator
+             $w configure -autoseparators 1
+         }
      }
  }
  
diff -c -r orig_2/tk8.4a2/library/tk.tcl try/tk8.4a2/library/tk.tcl
*** orig_2/tk8.4a2/library/tk.tcl	Tue Oct 31 02:12:38 2000
--- try/tk8.4a2/library/tk.tcl	Sat Jul  7 19:50:09 2001
***************
*** 281,286 ****
--- 281,288 ----
  	event add <<Copy>> <Control-Key-c> <Key-F16>
  	event add <<Paste>> <Control-Key-v> <Key-F18>
  	event add <<PasteSelection>> <ButtonRelease-2>
+ 	event add <<Undo>> <Control-Key-z>
+ 	event add <<Redo>> <Control-Key-Z>
  	# Some OS's define a goofy (as in, not <Shift-Tab>) keysym
  	# that is returned when the user presses <Shift-Tab>.  In order for
  	# tab traversal to work, we have to add these keysyms to the 
***************
*** 302,307 ****
--- 304,311 ----
  	event add <<Copy>> <Control-Key-c> <Control-Key-Insert>
  	event add <<Paste>> <Control-Key-v> <Shift-Key-Insert>
  	event add <<PasteSelection>> <ButtonRelease-2>
+   	event add <<Undo>> <Control-Key-z>
+ 	event add <<Redo>> <Control-Key-y>
      }
      "macintosh" {
  	event add <<Cut>> <Control-Key-x> <Key-F2> 
***************
*** 309,314 ****
--- 313,320 ----
  	event add <<Paste>> <Control-Key-v> <Key-F4>
  	event add <<PasteSelection>> <ButtonRelease-2>
  	event add <<Clear>> <Clear>
+ 	event add <<Undo>> <Control-Key-z>
+ 	event add <<Redo>> <Control-Key-Z>
      }
  }
  
diff -c -r orig_2/tk8.4a2/mac/tkMacDefault.h try/tk8.4a2/mac/tkMacDefault.h
*** orig_2/tk8.4a2/mac/tkMacDefault.h	Fri Jul 28 18:34:55 2000
--- try/tk8.4a2/mac/tkMacDefault.h	Sat Jul  7 19:46:34 2001
***************
*** 419,424 ****
--- 419,425 ----
   * Defaults for texts:
   */
  
+ #define DEF_TEXT_AUTO_SEPARATORS	"1"
  #define DEF_TEXT_BG_COLOR		NORMAL_BG
  #define DEF_TEXT_BG_MONO		WHITE
  #define DEF_TEXT_BORDER_WIDTH		"0"
***************
*** 453,458 ****
--- 454,460 ----
  #define DEF_TEXT_STATE			"normal"
  #define DEF_TEXT_TABS			""
  #define DEF_TEXT_TAKE_FOCUS		(char *) NULL
+ #define DEF_TEXT_UNDO    		"0"
  #define DEF_TEXT_WIDTH			"80"
  #define DEF_TEXT_WRAP			"char"
  #define DEF_TEXT_XSCROLL_COMMAND	""
diff -c -r orig_2/tk8.4a2/tests/text.test try/tk8.4a2/tests/text.test
*** orig_2/tk8.4a2/tests/text.test	Tue Jul 25 02:05:40 2000
--- try/tk8.4a2/tests/text.test	Sat Jul  7 20:00:20 2001
***************
*** 51,56 ****
--- 51,57 ----
  text .t2
  set i 0
  foreach test {
+     {-autoseparators yes 1 nah}
      {-background #ff00ff #ff00ff <gorp>}
      {-bd 4 4 foo}
      {-bg blue blue #xx}
***************
*** 83,88 ****
--- 84,90 ----
      {-spacing3 -10 0 bogus}
      {-state d disabled foo}
      {-tabs {1i 2i 3i 4i} {1i 2i 3i 4i} bad_tabs}
+     {-undo 1 1 eh}
      {-width 73 73 2.4}
      {-wrap w word bad_wrap}
  } {
***************
*** 111,117 ****
  	lappend result [lindex $i 4]
      }
      set result
! } {blue {} {} 7 watch 0 {} fixed #012 5 #123 #234 0 green 45 100 47 2 3 82 raised #ffff01234567 21 yellow 0 0 0 0 disabled {1i 2i 3i 4i} {any old thing} 73 word {x scroll command} {test command}}
  
  test text-2.1 {Tk_TextCmd procedure} {
      list [catch {text} msg] $msg
--- 113,119 ----
  	lappend result [lindex $i 4]
      }
      set result
! } {1 blue {} {} 7 watch 0 {} fixed #012 5 #123 #234 0 green 45 100 47 2 3 82 raised #ffff01234567 21 yellow 0 0 0 0 disabled {1i 2i 3i 4i} {any old thing} 1 73 word {x scroll command} {test command}}
  
  test text-2.1 {Tk_TextCmd procedure} {
      list [catch {text} msg] $msg
***************
*** 150,156 ****
  } {1 {wrong # args: should be ".t option ?arg arg ...?"}}
  test text-3.2 {TextWidgetCmd procedure} {
      list [catch {.t gorp 1.0 z 1.2} msg] $msg
! } {1 {bad option "gorp": must be bbox, cget, compare, configure, debug, delete, dlineinfo, dump, get, image, index, insert, mark, scan, search, see, tag, window, xview, or yview}}
  
  test text-4.1 {TextWidgetCmd procedure, "bbox" option} {
      list [catch {.t bbox} msg] $msg
--- 152,158 ----
  } {1 {wrong # args: should be ".t option ?arg arg ...?"}}
  test text-3.2 {TextWidgetCmd procedure} {
      list [catch {.t gorp 1.0 z 1.2} msg] $msg
! } {1 {bad option "gorp": must be bbox, cget, compare, configure, debug, delete, dlineinfo, dump, edit, get, image, index, insert, mark, scan, search, see, tag, window, xview, or yview}}
  
  test text-4.1 {TextWidgetCmd procedure, "bbox" option} {
      list [catch {.t bbox} msg] $msg
***************
*** 218,224 ****
  } {1 {bad comparison operator "z": must be <, <=, ==, >=, >, or !=}}
  test text-6.14 {TextWidgetCmd procedure, "compare" option} {
      list [catch {.t co 1.0 z 1.2} msg] $msg
! } {1 {bad option "co": must be bbox, cget, compare, configure, debug, delete, dlineinfo, dump, get, image, index, insert, mark, scan, search, see, tag, window, xview, or yview}}
  
  # "configure" option is already covered above
  
--- 220,226 ----
  } {1 {bad comparison operator "z": must be <, <=, ==, >=, >, or !=}}
  test text-6.14 {TextWidgetCmd procedure, "compare" option} {
      list [catch {.t co 1.0 z 1.2} msg] $msg
! } {1 {bad option "co": must be bbox, cget, compare, configure, debug, delete, dlineinfo, dump, edit, get, image, index, insert, mark, scan, search, see, tag, window, xview, or yview}}
  
  # "configure" option is already covered above
  
***************
*** 227,233 ****
  } {1 {wrong # args: should be ".t debug boolean"}}
  test text-7.2 {TextWidgetCmd procedure, "debug" option} {
      list [catch {.t de 0 1} msg] $msg
! } {1 {bad option "de": must be bbox, cget, compare, configure, debug, delete, dlineinfo, dump, get, image, index, insert, mark, scan, search, see, tag, window, xview, or yview}}
  test text-7.3 {TextWidgetCmd procedure, "debug" option} {
      .t debug true
      .t deb
--- 229,235 ----
  } {1 {wrong # args: should be ".t debug boolean"}}
  test text-7.2 {TextWidgetCmd procedure, "debug" option} {
      list [catch {.t de 0 1} msg] $msg
! } {1 {bad option "de": must be bbox, cget, compare, configure, debug, delete, dlineinfo, dump, edit, get, image, index, insert, mark, scan, search, see, tag, window, xview, or yview}}
  test text-7.3 {TextWidgetCmd procedure, "debug" option} {
      .t debug true
      .t deb
***************
*** 310,316 ****
  } {1 {wrong # args: should be ".t index index"}}
  test text-10.3 {TextWidgetCmd procedure, "index" option} {
      list [catch {.t in a b} msg] $msg
! } {1 {bad option "in": must be bbox, cget, compare, configure, debug, delete, dlineinfo, dump, get, image, index, insert, mark, scan, search, see, tag, window, xview, or yview}}
  test text-10.4 {TextWidgetCmd procedure, "index" option} {
      list [catch {.t index @xyz} msg] $msg
  } {1 {bad text index "@xyz"}}
--- 312,318 ----
  } {1 {wrong # args: should be ".t index index"}}
  test text-10.3 {TextWidgetCmd procedure, "index" option} {
      list [catch {.t in a b} msg] $msg
! } {1 {bad option "in": must be bbox, cget, compare, configure, debug, delete, dlineinfo, dump, edit, get, image, index, insert, mark, scan, search, see, tag, window, xview, or yview}}
  test text-10.4 {TextWidgetCmd procedure, "index" option} {
      list [catch {.t index @xyz} msg] $msg
  } {1 {bad text index "@xyz"}}
***************
*** 369,375 ****
      list [.t get 1.0 1.end] [.t tag ranges bold] [.t tag ranges silly]
  } {{First second} {1.0 1.5} {1.5 1.12}}
  
! # Mark, scan, search, see, tag, window, xview, and yview actions are tested elsewhere.
  
  test text-12.1 {ConfigureText procedure} {
      list [catch {.t2 configure -state foobar} msg] $msg
--- 371,377 ----
      list [.t get 1.0 1.end] [.t tag ranges bold] [.t tag ranges silly]
  } {{First second} {1.0 1.5} {1.5 1.12}}
  
! # Edit, mark, scan, search, see, tag, window, xview, and yview actions are tested elsewhere.
  
  test text-12.1 {ConfigureText procedure} {
      list [catch {.t2 configure -state foobar} msg] $msg
***************
*** 1365,1370 ****
--- 1367,1485 ----
      tkTextSetCursor .t 3.0
      .t search -backward -regexp "\$" insert 1.0
  } {2.6}
+ 
+ test text-25.1 {TextEditCmd procedure, argument parsing} {
+     list [catch {.t edit} msg] $msg
+ } {1 {wrong # args: should be ".t edit option ?arg arg ...?"}}
+ 
+ test text-25.2 {TextEditCmd procedure, argument parsing} {
+     list [catch {.t edit gorp} msg] $msg
+ } {1 {bad edit option "gorp": must be modified, redo, reset, separator or undo}}
+ 
+ test text-25.3 {TextEditUndo procedure, undoing changes} {
+     catch {destroy .t}
+     text .t -undo 1
+     pack .t
+     .t insert end "line 1\n"
+     .t delete 1.4 1.6
+     .t insert end "should be gone after undo\n"
+     .t edit undo
+     .t get 1.0 end
+ } "line\n\n"
+ 
+ test text-25.4 {TextEditRedo procedure, redoing changes} {
+     catch {destroy .t}
+     text .t -undo 1
+     pack .t
+     .t insert end "line 1\n"
+     .t delete 1.4 1.6
+     .t insert end "should be back after redo\n"
+     .t edit undo
+     .t edit redo
+     .t get 1.0 end
+ } "line\nshould be back after redo\n\n"
+ 
+ test text-25.5 {TextEditUndo procedure, resetting stack} {
+     catch {destroy .t}
+     text .t -undo 1
+     pack .t
+     .t insert end "line 1\n"
+     .t delete 1.4 1.6
+     .t insert end "should be back after redo\n"
+     .t edit reset
+     catch {.t edit undo} msg
+     set msg
+ } "nothing to undo"
+ 
+ test text-25.6 {TextEditCmd procedure, insert separator} {
+     catch {destroy .t}
+     text .t -undo 1
+     pack .t
+     .t insert end "line 1\n"
+     .t edit separator
+     .t insert end "line 2\n"
+     .t edit undo
+     .t get 1.0 end
+ } "line 1\n\n"
+ 
+ test text-25.7 {-autoseparators configuration option} {
+     catch {destroy .t}
+     text .t -undo 1 -autoseparators 0
+     pack .t
+     .t insert end "line 1\n"
+     .t delete 1.4 1.6
+     .t insert end "line 2\n"
+     .t edit undo
+     .t get 1.0 end
+ } "\n"
+ 
+ test text-25.8 {TextEditCmd procedure, modified flag} {
+     catch {destroy .t}
+     text .t
+     pack .t
+     .t insert end "line 1\n"
+     .t edit modified
+ } {1}
+ 
+ test text-25.9 {TextEditCmd procedure, reset modified flag} {
+     catch {destroy .t}
+     text .t
+     pack .t
+     .t insert end "line 1\n"
+     .t edit modified 0
+     .t edit modified
+ } {0}
+ 
+ test text-25.10 {TextEditCmd procedure, set modified flag} {
+     catch {destroy .t}
+     text .t
+     pack .t
+     .t edit modified 1
+     .t edit modified
+ } {1}
+ 
+ test text-25.11 {<<Modified>> virtual event} {
+     set ::retval unmodified
+     catch {destroy .t}
+     text .t -undo 1
+     pack .t
+     bind .t <<Modified>> "set ::retval modified"
+     update idletasks
+     .t insert end "nothing special\n"
+     set ::retval
+ } {modified}
+ 
+ test text-25.12 {<<Selection>> virtual event} {
+     set ::retval no_selection
+     catch {destroy .t}
+     text .t -undo 1
+     pack .t
+     bind .t <<Selection>> "set ::retval selection_changed"
+     update idletasks
+     .t insert end "nothing special\n"
+     .t tag add sel 1.0 1.1
+     set ::retval
+ } {selection_changed}
  
  eval destroy [winfo child .]
  option clear
Only in try/tk8.4a2/unix: Makefile
Only in try/tk8.4a2/unix: config.cache
Only in try/tk8.4a2/unix: config.log
Only in try/tk8.4a2/unix: config.status
Only in try/tk8.4a2/unix: tkConfig.sh
diff -c -r orig_2/tk8.4a2/unix/tkUnixDefault.h try/tk8.4a2/unix/tkUnixDefault.h
*** orig_2/tk8.4a2/unix/tkUnixDefault.h	Fri Jul 28 18:34:55 2000
--- try/tk8.4a2/unix/tkUnixDefault.h	Sat Jul  7 19:46:05 2001
***************
*** 409,414 ****
--- 409,415 ----
   * Defaults for texts:
   */
  
+ #define DEF_TEXT_AUTO_SEPARATORS	"1"
  #define DEF_TEXT_BG_COLOR		NORMAL_BG
  #define DEF_TEXT_BG_MONO		WHITE
  #define DEF_TEXT_BORDER_WIDTH		"2"
***************
*** 443,448 ****
--- 444,450 ----
  #define DEF_TEXT_STATE			"normal"
  #define DEF_TEXT_TABS			""
  #define DEF_TEXT_TAKE_FOCUS		(char *) NULL
+ #define DEF_TEXT_UNDO    		"0"
  #define DEF_TEXT_WIDTH			"80"
  #define DEF_TEXT_WRAP			"char"
  #define DEF_TEXT_XSCROLL_COMMAND	""
diff -c -r orig_2/tk8.4a2/win/tkWinDefault.h try/tk8.4a2/win/tkWinDefault.h
*** orig_2/tk8.4a2/win/tkWinDefault.h	Fri Jul 28 18:34:56 2000
--- try/tk8.4a2/win/tkWinDefault.h	Sat Jul  7 19:46:57 2001
***************
*** 414,419 ****
--- 414,420 ----
   * Defaults for texts:
   */
  
+ #define DEF_TEXT_AUTO_SEPARATORS	"1"
  #define DEF_TEXT_BG_COLOR		"SystemWindow"
  #define DEF_TEXT_BG_MONO		WHITE
  #define DEF_TEXT_BORDER_WIDTH		"2"
***************
*** 448,453 ****
--- 449,455 ----
  #define DEF_TEXT_STATE			"normal"
  #define DEF_TEXT_TABS			""
  #define DEF_TEXT_TAKE_FOCUS		(char *) NULL
+ #define DEF_TEXT_UNDO    		"0"
  #define DEF_TEXT_WIDTH			"80"
  #define DEF_TEXT_WRAP			"char"
  #define DEF_TEXT_XSCROLL_COMMAND	""
Deleted tip/26.tip.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358






































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TIP:            26
Title:          Enhancements for the Tk Text Widget
Version:        $Revision: 1.8 $
Author:         Ludwig Callewaert <[email protected]>
Author:         Ludwig Callewaert <[email protected]>
State:          Accepted
Type:           Project
Vote:           Done
Created:        20-Feb-2001
Post-History:   
Discussions-To: news:comp.lang.tcl
Obsoletes:      19
Tcl-Version:    8.4

~ Abstract

This TIP proposes several enhancements for the Tk text widget.  An
unlimited undo/redo mechanism is proposed, with several user available
customisation features.  Related to this, a text modified indication
is proposed.  This means that the user can set, query or receive a virtual
event when the content of the text widget is modified.  And finally a
virtual event is added that is generated whenever the selection
changes in the text widget.

~ Rationale

The text widget provides a lot of features that make it ideally suited
to create a text editor from it.  The vast number of editors that are
based on this widget are a proof of this.  Yet some basic features are
missing from the text widget and need to be re-invented over and over
again by the authors of the various editors.  This TIP adds a number
of the missing features.

A first missing feature is an undo/redo mechanism.  The mechanism
proposed here is simple yet powerful enough to accommodate a very
reasonable undo/redo strategy.  It also provides sufficient user
control, so that the actual strategy can be refined and tailored to
the users need.

A second missing feature is a notification if the text in the widget
has been modified with respect to a reference point.  [19] deals
partly with this.  This implementation takes it some steps further.
First of all, there is a link with the undo/redo mechanism, since
undoing or redoing changes can take you to or away from the reference
point, and as such changes the modified state of the widget.
Secondly, with this implementation, a virtual event is generated
whenever the modified state of the widget changes, allowing the user
to bind to that event and for instance give a visual indication of the
modified state of the widget.

Finally, a virtual event has been added that is triggered whenever the
selection in the widget changes.  At first it may seem not so useful,
but there are a number of situations where this functionality is
needed.  A couple of examples where I ran into the need for this may
clarify this.  On Windows, if the text widget does not have the focus,
the selection tag is not visible.  This is consistent with other
Windows applications.  However, when implementing a search mechanism,
the found string needs to be tagged with the selection tag.  (You want
it to be selected).  The search (and replace) dialog box has the focus
however, so this selection tag is invisible.  To make it visible,
another tag was used to duplicate the selection tag.  This is very
easy when the functionality described here is available.  Otherwise it
is very difficult to do this consistently.  Another occasion was when
I was implementing a rectangular cut and paste for the text widget.
This was based on adding spaces on the fly, while selecting the
rectangle.  If for some reason the selection changes (for instance on
Unix another application gets the selection) these spaces need to be
removed again.  Doing this is virtually impossible without this
functionality.  With it, it becomes trivial.  The functionality itself
adds little or no overhead to the text widget.

~ Specification

The undo/redo mechanism operates by adding two stacks of edit actions
to the text widget.  Every insert or delete operation is added to the
undo stack in normal operation.  At certain times a separator is added 
onto the stack.  All insert and delete actions in between two separators
are considered to be one edit action, and will be undone or redone as one.  
The insertion of the separators is under user control.  There is a 
default operation however.  This will insert separators whenever the 
mode changes from insertion to deletion, or vise versa.  Separators are
also inserted when the keyboard or the mouse are used to move the insert
mark. Finally, pressing the <Return> key also inserts a separator. 
By turning the autoseparators off and inserting them at the desired 
points, compound actions, such as search and replace, can be created.  
The default paste function is an example of such an action.

Undoing an action, will re-apply in reverse order all inserts and
deletes in between two separators.  These inserts and deletes will now
move to the redo stack.  Redoing a change re-applies the inserts and
deletes, and moves them again to the undo stack.  Normal insertions or
deletions will clear the redo stack.

It is also possible to clear the undo stack, giving the user some control
over the depth of the stack.

Currently only text inserts and deletes can be undone. All other changes
to the widget, such as the adding or deleting of tags, cannot be undone.

The modified state of the widget is implemented using a counter.
Every insert or delete action, and every time such an action is redone,
increments this counter. Every undone insert or delete decrements this 
counter.  The widget is considered to be modified if the counter is not
zero.  A virtual event ''<<Modified>>'' is generated whenever this 
counter changes from zero to non-zero or vice versa.  A mechanism is 
provided to reset the counter to zero. The modified state can also be 
explicitely set by the user. In that case, the counter mechanism is not 
operational until the modified state has been reset again.

   1.  ''pathName configure -undo 0|1'' - this enables or disables the
       undo/redo mechanism.  The default is zero.

   2.  ''pathName configure -autoseparators 0|1'' - when one inserts
       a separator automatically whenever insert changes to delete or
       vice versa. Separators are also inserted when the keyboard or
       the mouse is used to move the insert mark, or when the <Return>
       key is pressed. When off, no separators are inserted, except by
       the user (See 6).  The default is one.

   3.  ''pathName edit undo'' - undoes the last edit action if undo is
       enabled (See 1). The insert mark will be positioned at the last
       undone edit action. When undo deletes text, that is the index
       where the text was. When undo inserts text, the insert mark
       will be positioned at the end of the inserted text. The view will
       be adapted to make the insert mark visible. Raises an exception 
       if there is nothing to undo. Does nothing if undo is disabled.

   4.  ''pathName edit redo'' - redoes the last edit action if undo is
       enabled (See 1). The insert mark and widget view will be updated
       similar to what is done for the edit undo command. Raises an 
       exception if there is nothing to redo.  Does nothing if undo is 
       disabled.

   5.  ''pathName edit reset'' - resets the undo and redo stacks
       (clears them).

   6.  ''pathName edit separator'' - inserts a separator on
       the undo stack, indicating an undo boundary.  If a separator is
       already present, this will do nothing.  This means that it is
       safe to issue the command several times, without any inserts or
       deletes occurring in between.

   7.  ''pathName edit modified ?boolean?'' - If boolean is not 
       specified returns the modified state of the widget 
       (either 1 or zero).
       If boolean is specified, sets the modified state of the widget 
       to that value.

   8.  ''<<Modified>>'' - this virtual event is generated whenever the
       modified state of the widget changes from modified to not
       modified or vice versa.

   9.  ''<<Selection>>'' - this virtual event is generated whenever
       the range tagged with the selection tag changes.

  10. ''<<Undo>>'' - this virtual event calls pathName edit undo.

  11. ''<<Redo>>'' - this virtual event calls pathName edit redo.

  12.  ''<Control-z>'' - is bound to the <<Undo>> virtual event.

  13.  ''<Control-Z>'' - is bound to the <<Redo>> virtual event on all
       platforms except Win32.

  14.  ''<Control-y>'' - is bound to the <<Redo>> virtual event on Win32.

~ Example

  The following code illustrates how the new features are intended to
  be used.

|   global fileName
|   global modState
|   global undoVar
|   
|   set fileName "None"
|   set modState ""
|   set undoVar  0
|   
|   
|   text .t -background white -wrap none
|   # Example 1: The Modified event will update a text label
|   bind .t <<Modified>>  updateState
|   # Example 2: The Selection event will create a tag that
|   #            duplicates the selection
|   bind .t <<Selection>> duplicateSelection
|   
|   frame .l
|   label .l.l -text "File: "
|   label .l.f -textvariable fileName
|   label .l.m -textvariable modState
|   
|   grid .l.l -sticky w   -column 0 -row 0
|   grid .l.f -sticky w   -column 1 -row 0
|   grid .l.m -sticky e   -column 2 -row 0
|   
|   grid columnconfigure .l 1 -weight 1
|   
|   frame .b
|   button .b.l -text "Load"   -width 8 -command loadFile
|   button .b.s -text "Save"   -width 8 -command saveFile
|   button .b.i -text "Indent" -width 8 -command blockIndent
|   
|   checkbutton .b.e -text "Enable Undo" -onvalue 1 -offvalue 0 -|   |   variable undoVar
|   trace variable undoVar w setUndo
|   button .b.u -text "Undo"     -width 8 -command "undo"
|   button .b.r -text "Redo"     -width 8 -command "redo"
|   button .b.m -text "Modified" -width 8 -command ".t edit modified on"
|   
|   grid .b.l -row 0 -column 0
|   grid .b.s -row 0 -column 1
|   grid .b.i -row 0 -column 2
|   grid .b.e -row 0 -column 3
|   grid .b.u -row 0 -column 4
|   grid .b.r -row 0 -column 5
|   grid .b.m -row 0 -column 6
|   
|   grid columnconfigure .b 0 -weight 1
|   grid columnconfigure .b 1 -weight 1
|   grid columnconfigure .b 2 -weight 1
|   grid columnconfigure .b 3 -weight 1
|   grid columnconfigure .b 4 -weight 1
|   grid columnconfigure .b 5 -weight 1
|   
|   
|   grid .l -sticky ew   -column 0 -row 0
|   grid .t -sticky news -column 0 -row 1
|   grid .b -sticky ew   -column 0 -row 2
|   
|   grid rowconfigure    . 1 -weight 1
|   grid columnconfigure . 0 -weight 1
|   
|   
|   
|   proc updateState {args} {
|      global modState
|      
|      # Check the modified state and update the label
|      if { [.t edit modified] } {
|         set modState "Modified"
|      } else {
|         set modState ""
|      }
|   }
|   
|   
|   proc setUndo {args} {
|      global undoVar
|      
|      # Turn undo on or off
|      if { $undoVar } {
|         .t configure -undo 1
|      } else {
|         .t configure -undo 0
|      }
|   }
|   
|   proc undo {} {
|      # edit undo throws an exception when there is nothing to
|      # undo. So catch it.
|      if { [catch {.t edit undo}] } {
|         bell
|      }
|   }
|   
|   proc redo {} {
|      # edit redo throws an exception when there is nothing to
|      # undo. So catch it.
|      if { [catch {.t edit redo}] } {
|         bell
|      }
|   }
|   
|   proc loadFile {} {
|      
|      set file [tk_getOpenFile]
|      if { ![string equal $file ""] } {
|         set fileName $file
|         set f [open $file r]
|         set content [read $f]
|         set oldUndo [.t cget -undo]
|         
|         # Turn off undo. We do not want to be able to undo
|         # the loading of a file
|         .t configure -undo 0
|         .t delete 1.0 end
|         .t insert end $content
|         # Reset the modified state
|         .t edit modified 0
|         # Clear the undo stack
|         .t edit reset
|         # Set undo to the old state
|         .t configure -undo $oldUndo
|      }
|   }
|   
|   proc saveFile {} {
|      # The saving bit is not actually done
|      # So the contents in the file are not updated
|   
|      # Saving clears the modified state
|      .t edit modified 0
|      # Make sure there is a separator on the undo stack
|      # So we can get back to this point with the undo
|      .t edit separator
|   }
|   
|   proc blockIndent {} {
|      set indent "   "
|      
|      # Block indent should be treated as one operation from
|      # the undo point of view
|      
|      # if there is a selection
|      if { ![catch {.t index sel.first} ] } {
|         scan [.t index sel.first] "%d.%d" startline startchar
|         scan [.t index sel.last]  "%d.%d" stopline  stopchar
|         if { $stopchar == 0 } {
|            incr stopline -1
|         }
|         
|         # Get the original autoseparators state
|         set oldSep [.t cget -autoseparators]
|         # Turn of automatic insertion of separators
|         .t configure -autoseparators 0
|         # insert a separator before the edit operation
|         .t edit separator
|         for {set i $startline} { $i <= $stopline} {incr i} {
|            .t insert "$i.0" $indent
|         }
|         .t tag add sel $startline.0 "$stopline.end + 1 char"
|         # insert a separator after the edit operation
|         .t edit separator
|         # put the autoseparators back in their original state
|         .t configure -autoseparators $oldSep
|      }
|   }
|   
|   proc duplicateSelection {args} {
|      .t tag configure dupsel -background tomato
|      .t tag remove dupsel 1.0 end
|      
|      if { ![catch {.t index sel.first} ] } {
|         eval .t tag add dupsel [.t tag ranges sel]
|      }
|   }
|   

~ Reference Implementation

http://www.cs.man.ac.uk/fellowsd-bin/TIP/26.patch

''The patch has received little testing so far, so any testing is
encouraged.''

~ Copyright

This document has been placed in the public domain.
Deleted tip/27.tip.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307



















































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TIP:            27
Title:          CONST Qualification on Pointers in Tcl API's
Version:        $Revision: 1.5 $
Author:         Kevin Kenny <[email protected]>
State:          Accepted
Type:           Project
Vote:           Done
Created:        25-Feb-2001
Post-History:   
Discussions-To: news:comp.lang.tcl,mailto:[email protected]
Tcl-Version:    8.4

~ Abstract

Many of the C and C++ interfaces to the Tcl library lack a CONST
qualifier on the parameters that accept pointers, even though they do
not, in fact, modify the data that the pointers designate.  This lack
causes a persistent annoyance to C/C++ programmers.  Not only is the
code needed to work around this problem more verbose than required; it
also can lead to compromises in type safety.  This TIP proposes that
the C interfaces for Tcl be revised so that functions that accept
pointers to constant data have type signatures that reflect the fact.
The new interfaces will remain backward-compatible with the old,
except that a few must be changed to return pointers to CONST data.
(Changes of this magnitude, in the past, have been routine in minor
releases; the author of this TIP does not see a compelling reason to
wait for Tcl 9.0 to clean up these API's.)

~ Rationale

When the Tcl library was originally written, the ANSI C standard had
yet to be widely accepted, and the ''de facto'' standard language did
not support a ''const'' qualifier.  For this reason, none of the older
Tcl API's that accept pointers have CONST qualifiers, even when it is
known that the objects will not be modified.

In interfacing with other systems whose API's were designed after the
ANSI C standard, this limitation becomes annoying.  Code like:

| const char* const string = " ... whatever ... ";
| Tcl_SetStringObj( Tcl_GetObjResult( interp ),
|                   (char*) string, /* Have to cast away
|                                    * const-ness here
|                                    * even though the string
|                                    * will only be copied
|                                    */
|                   -1 );

is more verbose than necessary.  It is also unsafe: the cast allows a
number of unsafe type conversions (the author of this TIP has had to
debug at least one extension where an integer was cast to a character
pointer in this context).

In an C++ environment where engineering practice forbids using C-style
cast syntax, the syntax gets even more annoying, although it provides
improved safety.  C++ code analogous to the above snippet looks like:

| const char* const string = "...whatever...";
| Tcl_SetStringObj( Tcl_GetObjResult( interp ),
|                   const_cast< char* >( string ), -1 );

This code is hardly a paragon of readability.

The popular Gnu C compiler also has a problem with the ''char *''
declaration of so many of the parameters.  With the default set of
compilation options, a call like:

| Tcl_SetStringObj( Tcl_GetObjResult( interp ),
|                   "Hello world!", -1 );

results in an error; suppressing this message requires either using
the obscure option ''-fwritable-strings'' on the compiler command
line, or else applying awkward (and unsafe) cast syntax:

| Tcl_SetStringObj( Tcl_GetObjResult( interp ),
|                   const_cast< char* >( "Hello, world!" ), -1 );

Introducing CONST on parameters, however, does not bring in any
incompatibility; as long as there is a prototype in scope, any
ANSI-compliant compiler will implicitly cast non-CONST arguments to be
type-compatible with CONST formal parameters.

~ Specification

This TIP proposes that, wherever possible, Tcl API's that accept
pointers to constant data have their signatures in ''tcl.decls'' and
the corresponding source files adjusted to add the CONST qualifier.

The change introduces a potential incompatibility in that code
compiled on a (hypothetical) architecture where pointers to constant
data have a different representation from those to non-constant
data will not load against the revised stub table.  This incompatibility
is, in fact, not thought to be a problem, since no known port of
Tcl has encountered such an architecture.

If we confine the scope of this TIP to adding CONST only to
parameters, we preserve complete compatibility with existing
implementations.  It is neither possible nor desirable, however, to
preserve drop-in compatibility across all the API's.  The earliest
example in the stub table is the ''Tcl_PkgRequireEx'' function.  This
function is declared to return ''char *''; the pointer it returns,
however, is into memory managed by the Tcl library.  Any attempt by an
extension to scribble on this memory or free it will result in
corruption of Tcl's internal data structures; it is therefore safer
and more informative to return ''CONST char *''.  (This particular
example is also highly unlikely to break any existing extension; the
author of this TIP has yet to see one actually use the return value.)

Some of the API's, such as ''Tcl_GetStringFromObj'', will continue to
return pointers into writable memory inside the Tcl library.
''Tcl_GetStringFromObj'', for instance, deals with memory that is
managed co-operatively between extensions and the Tcl library; one
simply must trust extensions to do the right thing (for instance, not
overwrite the string representation of a shared object).

Some of the API's will not be modified, even though they appear to
accept constant strings.  For instance, ''Tcl_Eval'' modifies its
string argument while it is parsing it, even though it restores its
initial content when it returns.  This behavior has sufficient impact
on performance that it is probably not desirable to change it.  The
cases where the Tcl library does this sort of temporary modification,
however, must be documented in the programmers' manual.  They affect
thread safety and positioning of data in read-only memory.  One can
foresee that cleaning up the API's that do not suffer from
this problem will mean that programmers will be  less tempted
to use unsafe casts on the ones that remain.

Finally, there are a handful of API's that are essentially impossible
to clean up portably; the ones that accept variable arguments come to
mind.  These will be left alone.  One particular case in point is
''Tcl_SetResult'': its third argument determines whether its second
argument is constant or non-constant.  In an environment without
writable strings, a call like:

|    Tcl_SetResult( interp, "Hello, world!", TCL_STATIC );

or

|    Tcl_SetResult( interp, "Hello, world!", TCL_VOLATILE );

cannot be handled without unsafe casting.  Fortunately, several
alternatives are available.  The most attractive appears to be:

|    Tcl_SetObjResult( interp, 
|                      Tcl_NewStringObj( "Hello, world!", -1 ) );

which is also more informative about what is really going on.  Note
that ''TCL_STATIC'' no longer actually carries the static pointer
around.  Although ''Tcl_SetResult'' appears to do so, as soon as the
command returns, code in ''tclExecute.c'' converts the string result
into an object result by calling ''Tcl_GetObjResult''.  The code using
''Tcl_SetObjResult'' therefore carries no greater performance cost
than the original ''Tcl_SetResult''.

~ Reference Implementation

The changes described in this TIP cut across too many functional areas
to be implemented effectively all at once.  Several people have
pointed out that implementing this cleanup all at once appears to be
necessary to avoid "CONST pollution," where the library becomes full
of code that casts away the CONST qualifier.  To study this issue, the
author has conducted the experiment of imposing CONST strings on the
first API in the stubs table: ''Tcl_PkgProvideEx''.

The first concern that arose was that several other functions used the
CONST strings passed as parameters, and these functions also needed to
be updated. Fortunately, all were static within ''tclPkg.c''.  Next,
when updating the documentation, the author discovered that five other
functions were documented in the same man page, and shared a common
defintion of the ''package'' and ''version'' parameters.  They, too,
were included in the change, and once again, the change was propagated
forward into the functions that they called.  (This activity is where
the issue of replacing ''Tcl_SetResult'' with ''Tcl_SetObjResult'' was
detected.)

When replacing ''Tcl_SetResult'' with ''Tcl_SetObjResult'', the author
discovered that the ''file'' parameter to ''Tcl_DbNewStringObj'' was
also a constant string.  With more enthusiasm than caution, he decided
to attack the corresponding parameter in all the ''TCL_MEM_DEBUG''
interfaces.  (In retrospect, it would probably have been easier to
tackle this issue separately.)  This change wound up
cutting across virtually all of the external interfaces to
''tclStringObj.c'' and ''tclBinary.c'' and the associated
documentation.

The author expects that many of the other API's will be much less
closely coupled than the one studied. In particular, now that the
interfaces of ''tclStringObj.c'' have been done once, they don't need
to be done again!  In fact, starting with the interfaces, like
''tclStringObj.c'', that are used pervasively throughout the library
and working outward would certainly have been a better course of
action than tracing the dependencies forward from one function chosen
almost at random.

The result of the experimental change was that twenty-eight external
APIs, plus about a dozen static functions, needed to have the CONST
qualifier added to at least one pointer.  After these changes were
made, the test suite compiled, linked, and passed all regression tests
with all combinations of the NODEBUG and TCL_MEM_DEBUG options.  It
was nowhere necessary to cast away CONST-ness.  

Possible incompatibility with existing extensions was present
only in that the return values from the four functions,
''Tcl_PkgPresent'', ''Tcl_PkgPresentEx'', ''Tcl_PkgRequire'', and
''Tcl_PkgRequireEx'' had the CONST qualifier added.
 These four functions return pointers to memory
that must not be modified nor freed by the caller, so the CONST
qualifier is desirable, but existing extensions may depend on storing
the pointer in a variable that lacks the qualifier.
This level of incompatibility in a minor release has been
thought acceptable in the past; changes required to extensions
are trivial, and once changed, the extensions continue to back-port
cleanly to older releases.

An earlier version of these changes was uploaded to the SourceForge
patch manager as patch number 404026.  The revised version will be
added under the same patch number as soon as the author's technical
problems with uploading patches are resolved.  (The major difference
between the two patches is that the first patch implements the
two-Stub approach described under "Rejected alternatives" below.

The success of this change has convinced the author of this TIP that
the rest of the changes can be implemented in a staged manner, with
little source-level incompatibility being introduced for
extensions (and absolutely no incompatibility for stubs-enabled
extensions compiled and linked against earlier versions of the
library).

~ Rejected alternatives

The initial version of this TIP attempted to preserve backward
compatibility of stubs-enabled extensions, even on a hypothetical
architecture where pointer-to-constant and pointer-to-nonconstant
have different representations.

If this level of backward compatibility is desired,
it will be necessary to provide entries in the existing
stub table slots corresponding to the API's that lack the CONST
qualifiers.

The slots in the stub table corresponding to the non-CONST API's can
be filled with wrapper functions.  For example, the following function
definition of ''Tcl_SetStringObj_NONCONST'' will use the implicit
casting inherent in C to call the function with the new API.

|void
|Tcl_SetStringObj_NONCONST(Tcl_Obj* obj, /* Object to set */
|                          char* bytes,  /* String value to assign */
|                          int length)   /* Length of the string */
|{
|    Tcl_SetStringObj( obj, bytes, length );
|}

This sort of definition is so simple that ''tools/genStubs.tcl''
was extended in the original patch accompanying this TIP
to generate it.  For example, the declaration of
''Tcl_SetStringObj'' that once appeared as:

|declare 65 generic {
|    void Tcl_SetStringObj( Tcl_Obj* objPtr, char* bytes, int length )
|}

was replaced with:

|declare 458 -nonconst 65 generic {
|    void Tcl_SetStringObj( Tcl_Obj* objPtr, CONST char* bytes, int length )
|}

declaring that slot 458 in the stubs table is to be used for the new
API accepting a CONST char* for the string, while slot 65 remains used
for the legacy implementation.

The difficulty with this approach, which caused it to be
rejected, is that it introduces ''forward'' incompatibility.
Any extension compiled against header files from after the change
will fail to load against the stubs table from before the change.
This incompatibility would require extension authors to maintain
sets of header files for (at least) the earliest version of Tcl
that they intend to support, rather than always being able to compile
against the most current set.  This problem was thought to be worse
than the hypothetical and possibly non-existent problem of differing
pointer representations.

~ Procedural note

The intent of this TIP is that, if approved, it will empower
maintainers of individual modules to add ''CONST'' to any API
where it is appropriate, provided that:

   * the change does not introduce "CONST poisoning", that is,
     does not require type casts that remove CONST-ness;

   * the documentation of the API is updated to reflect the
     addition of the CONST qualifier; and

Individual TIP's detailing the changes to particular APIs shall
''not'' be required, provided that the changes comply with these
guidelines.

~ Change history

12 March 2001: Rejected the two-Stubs alternative and reworked
the patches to use only one Stub per modified function.

~ Copyright

This document has been placed in the public domain.
Deleted tip/28.tip.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583







































































































































































































































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TIP:            28
Title:          How to be a good maintainer for Tcl/Tk
Version:        $Revision: 1.9 $
Author:         Don Porter <[email protected]>
Author:          <[email protected]>
State:          Draft
Type:           Informative
Vote:           Pending
Created:        23-Feb-2001
Post-History:   

~ Abstract

This document presents information and advice to maintainers in the
form of a Frequently Asked Questions (FAQ) list.

~ Preface

Notice in the header above that this is a Draft document.  It won't be
the ''official'' word of the TCT unless/until it is accepted by the
TCT.  Meanwhile, it should still be a helpful guide to those serving
or considering service as maintainers.  At the very least it's a
useful straw man to revise into something better.  Help us make it
even more useful by using the [[Edit]] link at the bottom of this page
(if any) to add/revise the questions and answers, or add your
comments.

~ Background

TCT procedures (see [0]) calls for one or more ''maintainers'' to take
responsibility for each functional area of the Tcl ([16]) or Tk ([23])
source code.  Every source code patch to Tcl or Tk will be committed
to the official branches of the appropriate CVS repository only after
approval by an appropriate set of maintainers.

~ Can I be a Tcl/Tk maintainer?

Most likely.  To be a maintainer, you should have...

 * ...an interest in Tcl/Tk.

 * ...access to the Internet (Web and e-mail).

 * ...some volunteer time to contribute.

 * ...the ability and the support software to code in C and/or Tcl,
   use CVS, use SourceForge facilities, and familiarity with a portion
   of the Tcl/Tk source code to be maintained, or the willingness to
   acquire these things.

For the most part, if you are reading this document, you probably have
what it takes to be a Tcl/Tk maintainer.

~ What can I maintain?

The Tcl Core Team (TCT) has divided up the Tcl/Tk source code into
functional areas as described in [16] and [23].  You can volunteer to
help maintain as many areas as you think you can handle.  Select those
you have experience with or an interest in.

~ What does a maintainer do?

Maintainers are the people who make changes to the files that make up
the source code distribution of Tcl or Tk -- code, documentation, and
tests.  That's what a maintainer does: check in changes to the
official source code in the area he/she maintains.

The source code can be changed for several reasons: to correct a bug,
to add a new feature, or to re-implement an existing feature in a new
way.  The reason for a change controls how much oversight the
maintainer must have while making the change.  More on this below.

~ How do I prepare to be a maintainer?

The official repositories of Tcl and Tk source code are kept at
SourceForge, so you need to register for a SourceForge account
(https://sourceforge.net/account/register.php).  As part of the
registration, you will select a login name.  When you volunteer as a
maintainer, the administrators of the Tcl or Tk projects will need
that name to give you write access to the appropriate repository.

Once you have a SourceForge account, get familiar with the tools it
provides.  Most important is that you get set up to use CVS over SSH
to access the repository.  This can be difficult.  There are some
notes on how other Developers on the Tcl and Tk projects have been
able to successfully get this done at http://tcltk.org/sourceforge

This document does not include instructions on how to use CVS.  See
the following references for assistance with learning CVS.

  http://cvsbook.red-bean.com/cvsbook.html

  >	''Add more references here please.''

~ How do I volunteer to be a maintainer?

Send a message to <[email protected]> telling the TCT
your SourceForge login name and what area(s) you want to help
maintain.  Someone will add you to the list of ''Developers'' on the
Tcl or Tk projects and enable your access to SourceForge features like
the Bug Tracker and Patch Manager.  As a Developer, you will have
write access to the appropriate repository of official source code.

~ Write access!  So I can just start changing Tcl/Tk?!

For some purposes, yes.  For others, you'll need to get approval from
the TCT first.  Read on...

~ What Internet resources does a maintainer use?

A maintainer uses the SourceForge Bug Tracker for Tcl or Tk to learn
what bugs are reported in his area (browse by Category).

   http://sourceforge.net/bugs/?group_id=10894

   http://sourceforge.net/bugs/?group_id=12997

A maintainer uses the SourceForge Patch Manager for Tcl or Tk to learn
what patches make changes in his area (browse by Category).

   http://sourceforge.net/patch/?group_id=10894

   http://sourceforge.net/patch/?group_id=12997

A maintainer uses CVS via SSH to access, track, and modify the various
branches of development in the repository of official Tcl or Tk source
code.

|cvs -d :ext:[email protected]:/cvsroot/tcl \
|   checkout -r $BRANCH_TAG -d $LOCAL_DIR tcl
|
|cvs -d :ext:[email protected]:/cvsroot/tktoolkit \
|   checkout -r $BRANCH_TAG -d $LOCAL_DIR tk

A maintainer examines the state of Tcl Improvement Proposals (TIPs) and
adds his comments to them at the TIP Document Collection.

   http://purl.org/tcl/home/cgi-bin/tct/tip/

A maintainer may follow and participate in TCT discussions about TIPs
and other matters concerning Tcl/Tk development on the TCLCORE mailing
list.

   http://lists.sourceforge.net/lists/listinfo/tcl-core

A maintainer may receive e-mail notification every time any change is
made to any entry in Tcl's or Tk's Bug Tracker or Patch Manager by
subscribing to the TCLBUGS mailing list.

   http://lists.sourceforge.net/lists/listinfo/tcl-bugs

~ There are multiple maintainers in my area.  What do I do?

The maintainer tasks are the same; you just have more hands to get the
job done.  It is up to the maintainers of an area to decide among
themselves how they will divide the tasks.  They might each take on a
particular subset of files.  Or they might let some maintainers fix
bugs while others review new features.  Or they might appoint one
maintainer as the ''lead'' and let him assign tasks to the others.
Whatever works for you, and gets the work done.

~ I found a bug in my area.  What do I do?

Bug finding and reporting is a job for the whole community, so when
you find a bug, take off your maintainer hat.  Report it to the Bug
Tracker just like anyone would.  If you recognize that the bug is in
your area, go ahead and assign it to the Category for your area and to
yourself or one of the other maintainers who share responsibility for
that area.

~ Why do I report the bug to myself?

So that the bug appears in the database.  Someone else may find it
too, and when they go to report it to the Bug Tracker, they should
discover that it's an already reported problem.  A registered bug
report is also the place where progress on fixing the bug can be
recorded for all to see.

~ There's a bug reported in the Category for the area I maintain. What do I do?

First, understand the bug report.  The best bug reports are clear and
come with a demonstration script, but not all reports are so well
crafted.  You may need to exchange messages with the person who
reported the bug.  If the reporter logged in to SourceForge as
''username'' before submitting a report, then you can write back to
''[email protected]''.  If the bug was reported by
''nobody'', the best you can do is post a followup comment to the bug
asking for more information, and hope the reporter comes back to
check.

Next, confirm that the bug report is valid, original, and that it
belongs in your area.  Does it correctly assert that some public
interface provided by your area behaves differently from its
documented behavior?  If not, then you should take the appropriate
action:

  1. If the bug report notes a problem in another project, assign it
     to a Developer who is an Admin of the other project.  Add a
     comment asking them to reassign to the correct project.  Assigned
     To: ''an Admin of the other project''.

  >  If no Developer is an Admin of the other project, or the other
     project isn't hosted by SourceForge, note the error in a comment,
     and mark the report invalid.  Resolution: Invalid; Status:
     Closed; Assigned To: ''yourself''.

  1. If the bug report notes a problem due to a bug in another area,
     reassign it to the appropriate Category.  Category: ''correct
     category''

  1. If the reporter's expectations are incorrect, point them to the
     documentation.  You may also want to revise the documentation if
     it is not clear.  Resolution: Invalid; Status: Closed; Assigned
     To: ''yourself''.

  1. If the bug report notes a problem already noted by another bug
     report, note the duplication.  Resolution: Duplicate; Status:
     Closed; Assigned To: ''yourself''.

  1. If the bug report acknowledges that the code is behaving as
     documented, but argues that the documented behavior should be
     revised, then the report is a feature request rather than a bug
     report.  More on handling feature requests below.  Group: Feature
     Request.

Valid, original bug reports in your area should be assigned to a
maintainer of your area.  If you are the only maintainer of your area,
assign the bug to yourself.  If there are multiple maintainers, you
should decide among yourselves how to divide up the bug report
assignments.

~ There's a bug assigned to me.  What do I do?

Now we get the the heart of what a maintainer does.  This is where you
unleash the energies and talents you bring to the table.  So, the best
answer is "Do what works best for you." The rest of this answer should
be read as additional guidelines and tips that have worked well for
others and might help you, but not as a mandatory checklist you must
follow.  If some advice below seems more burdensome than helpful, fall
back to "Do what works best for you."  The goal is to register a patch
that fixes the bug with the SourceForge Patch Manager.  Do whatever
helps you accomplish that goal.

Try to enlist the assistance of the person who reported the bug.  This
is especially important if the problem is platform-specific on a
platform you do not have access to.  Gaining the participation of the
person who reported the bug can have many other benefits too.  They
see that progress is being made.  They can offer additional insights
they have, but left out of their original report.  They can see how
better bug reports lead to faster, better solutions, so their next
reports may be of higher quality.  They may even gain enough
experience that their next report may come with the correction already
attached.  Eventually, they may even become maintainers themselves.

First, try to develop a test that demonstrates the bug and add it to
the section of the test suite for your area.  If the original bug
report contained a demonstration script, perhaps you can adapt that.
The new test will help you verify when you have fixed the bug.

If a fix for the bug is offered with the report, give it a try.
Otherwise develop a fix yourself.  Take care that while fixing the
bug, you do not create new bugs by changing the correct behavior of
other parts of the code in your section.  The test suite for your area
is very helpful.  Use it.

It may become apparent that the best fix for your bug can only be
accomplished after another bug is fixed first, or perhaps after a new
feature is added to Tcl/Tk.  In those cases, add a comment to the
original bug report so those interested will know what is causing the
delay.  SourceForge may offer a way to denote these dependencies as
well.

If you have trouble fixing the bug, ask for help.  Try the other
maintainers of your area first.  Then try posting comments attached to
the original bug report.  Using ''cvs log'', you can get a list of
developers who've recently made changes to the files you maintain.
They might be able to offer advice, or explanations about why the code
is the way it is.  If none of these focused searches for help bears
fruit, then try broader requests to the TCLCORE mailing lists, or the
news:comp.lang.tcl newsgroup.

At any time, you may have several bugs assigned to you.  It will help
guide the expectations of the Tcl community if you can assign priority
values to the bugs indicating the importance you assign to them.  Try
to work on fixing higher priority bugs before lower priority bugs.
Some reasons you might give a bug a higher priority include:

    1. The bug causes a panic or core dump.

    1. Documentation is missing or incorrect.

    1. Other bug fixes are waiting on this bug fix.

    1. Several duplicate reports or "me too" comments about the bug
       are coming in from the community.

Some reasons you might give a bug a lower priority include:

    1. A workaround is identified (add it as a comment attached to the
       bug report).

    1. Feature requests tend to get lower priority since they should
       be handled through the TIP process.

Once you have crafted a fix for the bug, create a patch to the
official source code (including the new tests that test for the fixed
bug) and register it with the SourceForge Patch Manager.  Note the
number of the bug report fixed by the patch somewhere in the summary
or comments associated with the patch.  Assign the patch to yourself.
Assign the Category to the area you maintain.

~ There's a patch registered under the Category I maintain.  What do I do?

The SourceForge Patch Manager is used to review and revise patches
before they are committed to the official source code.  Your actions
depend on what the patch does to your area, and who the patch is
assigned to.  The patch may change the public interface provided by
your area (feature change); or the change may be completely internal
(bug fix, or re-implementation) within your area.  The patch may be
assigned to you, to someone else, or to nobody.  The person the patch
is assigned to is the person who is leading the effort to integrate
the patch into the official source code.

~ What if the patch is assigned to nobody?

The patch has probably been contributed by someone not on the list of
Developers.  It may be a contributed bug fix, or a contributed
implementation of a TIP.  Assign contributed bug fixes to the same
maintainer who is assigned the corresponding bug report.  If there is
no corresponding bug report, add one.  Assign TIP implementations to
the Developer identified in the TIP as the one responsible for
implementation of that TIP, or the TCT member who sponsored the TIP.

If the patch changes only your area (and shared or generated files),
then leave the Category in your area.  If the patch changes other
areas as well as yours, change the category to None.

~ What if the patch is assigned to me?

Presumably you've assigned it to yourself to indicate that you're
taking charge of integrating that patch into the official sources.  If
that's a mistake, treat the patch as if it were assigned to nobody.
If you are the one leading the integration effort, see below (How do I
integrate a patch into the official sources?).

~ What if the patch is assigned to someone else?

If the patch is assigned to another maintainer in your area, let him
handle it.  Leave it alone.

If the patch makes no changes in your area, change the Category of the
patch to None.

If the patch makes changes in your area, and is assigned to a
Developer who is not a maintainer of your area, that Developer is
asking for review of the patch's changes to your area.  You or one of
the other maintainers of your area should review the patch and accept
or reject it.  Read on...

~ What special review does a "feature change" patch require?

Changes to the public interface of your section must be proposed to
and accepted by the TCT through the TIP process before they can be
added to the official Tcl source code.  If the patch changes the
public interface of your section, then there should be an associated
TIP describing the new feature(s) that patch implements.  Until there
is such a TIP, and that TIP has been accepted by the TCT (check the
value of the State header), you should not approve the patch.

Once there is an approved TIP corresponding to the patch, you should
confirm that the patch correctly implements the accepted feature as
described by the TIP.  If not, you should not approve the patch.

After confirming that the patch correctly implements the feature
change described in an accepted TIP, you should still review the
technical merit of the patch's changes to your area before approving
it.

~ How do I review the technical merits of a patch?

Apply the patch and run the test suites that cover your area.  Check
that the patch does not add any new test failures.  If the patch is a
bug fix, check that it actually fixes the bug.  Think five times
before approving a patch that causes new test failures or incompletely
fixes a bug or incompletely implements an approved TIP.

Keep in mind that once the patch is integrated into the official
sources, you'll be expected to maintain it.  It is not in your
interest to approve patches that make your job harder.  Think four
times before approving a patch that you do not understand.

Check that the patch keeps the features offered on different platforms
consistent.  If not, be certain that the documentation properly notes
the platform-specific behavior.  Think three times before approving a
patch that causes the capabilities of Tcl/Tk to further diverge on
different platforms.

Check that the patch follows Tcl's established coding conventions.
See the Tcl/Tk Engineering Manual
(http://purl.org/tcl/home/doc/engManual.pdf) and the Tcl Style Guide
(http://purl.org/tcl/home/doc/styleGuide.pdf) for details.  This is
especially important when accepting contributed patches.  Think twice
before approving a patch that doesn't conform to these conventions.

Check the effect of the patch on the performance of Tcl/Tk.  Use the
tclbench set of benchmarks.

|cvs -d :pserver:[email protected]:/cvsroot/tcllib \
|      checkout tclbench

Think carefully before approving a patch that significantly degrades
the performance of important operations.

Finally, while examining the patch, you may see a better way to
accomplish the effect of the changes in your area.  If you can provide
that alternative implementation reasonably quickly, then propose it as
a revision to the patch.  However, be careful not to let the perfect
be the enemy of the good.  If a patch works, do not reject just
because you can imagine a better way it could be done.  Provide the
better way, or accept the less good way in the patch, and leave
migration to the better way for later when you have the time.

To approve the patch's changes to your area, simply note your approval
in a followup comment on the patch.  Indicate in your comment the
Category of the area for which you approve the changes.  If the patch
changes multiple areas, set the Category of the patch back to None.

To reject the patch, you also indicate your rejection in a followup
comment.  You should explain the reasons for your rejection so that
the patch can be revised with the goal of gaining your approval.  If
you can supply the needed revisions with reasonable effort, do so.  If
the patch changes multiple areas, set the Category of the patch back
to None.

Unless the patch is assigned to you, do not change the Status of the
patch.  Leave that to the Developer assigned to the patch.

~ How do I integrate a patch into the official sources?

First you need the approval of at least one maintainer of each section
changed by the patch.

~ How do I get approval for integration?

First, assign the patch to yourself to indicate that you are leading
the integration effort.  Next, determine the list of categories
corresponding to the areas changed by the patch.  It may help if you
list them in a comment attached to the patch.

For each category in the list, assign the Category of the patch to
that category.  Then wait for a maintainer for that area to review the
patch.  If one approves it, then assign the next Category in the list.
If maintainers for all areas on the list approve the same patch, you
may integrate the patch into the official sources.

If a maintainer rejects the patch, revise the patch to address his
concerns.  Then start the review again.  Start with the maintainer who
rejected the first patch to be sure his concerns are addressed first.

Note that if the patch changes only the area you maintain, then you
may immediately integrate the patch into the official sources once you
are satisfied with it and it is registered in the Patch Manager.

~ The patch is approved.  How should it be integrated?

Get a CVS working directory that is up to date with the HEAD branch of
the official source repository.  Apply the patch to your working
directory, and then 'cvs commit' the changes to the HEAD branch.

At the same time you commit the patch, be sure to add an entry to the
ChangeLog file describing the change.  Follow the established format,
which is derived from the GNU coding conventions.  The description
should be brief, but should describe the change reasonably completely.
Include the SourceForge Bug and Patch ID numbers in the ChangeLog
entry, but do not assume that the reader will have access to the Bug
Tracker and Patch Manager to be able to understand the entry.  You may
assume the reader has access to the documentation.

Finally, with the patch integrated, change the Status of the patch in
the Patch Manager to Accepted.  If any bugs were fixed by the patch,
change their Resolution to Fixed, and their Status to Closed.

~ I want a patch review even though the patch changes only my area.

Keep in mind that integrating a patch into the official sources is not
an irreversible act.  Commits to the HEAD branch will be checked out
and tested by members of the Tcl community who are tracking Tcl/Tk
development.  Alpha and beta releases of Tcl/Tk that include your
patch will also get your changes reviewed in practical settings.

That said, if you really want a pre-commit review of your patch, you
can add a comment to the patch asking for review.  Someone will
probably respond.  It's up to your judgment how long to wait, keeping
in mind that you are the maintainer, so your judgment on the quality
of patches in your area is implicitly trusted.

~ What about CVS branches?

When you integrate a patch into the official source code, you will
usually 'cvs commit' the patch onto the HEAD branch.  If the patch
includes a feature change, it must (except in unusual circumstances
approved by the TCT) be committed to the HEAD branch.  The HEAD branch
is the development branch from which alpha releases of Tcl/Tk are
generated.

At any time, there is also one or more ''stable'' branches of
development.  As of February, 2001, the branch 'core-8-3-1-branch'
indicates the sequence of revisions from which the 8.3.x releases of
Tcl/Tk are generated.

Since the Tcl Core Team took over development of Tcl/Tk, no changes
have been committed to a stable branch, so we really have not
established procedures on how we will decide what bug fixes should and
should not be applied to the stable branch.  It is possible that
maintainers will be involved, though.  It is also possible that a
special team will be appointed to update the stable branch in
preparation for the next stable release.  In the case that you as a
maintainer are asked to commit to the stable branch, be aware that the
only patches that should be committed to a stable branch are those
that fix bugs.  No new features should be committed here.

The other kind of branch is a ''feature'' branch.  This is a
development branch on which a sequence of several revisions may be
committed as work in progress on a new feature, or re-implementation
of existing features.  Typically a feature branch will be created if
the effort...

   * ...touches on several functional areas;

   * ...is worked on jointly by several Developers;

   * ...is complex enough to require several revisions;

   * ...needs prototyping to determine the best TIP proposal to make;
     or

   * ...makes an incompatible change to Tcl/Tk that properly belongs
     on the next major version of Tcl/Tk before the HEAD branch has
     been designated for work toward the next major version.

As a Developer, feel free to create a feature branch if you have a
reason to use one.  Make a note of your branch tags in [31].  Avoid
the use of a branch tag matching core-* .
Save the core-* branch tags for the tags of official stable branches
and releases.  To avoid conflict with other Developers, consider using
your SourceForge login name as a prefix on the feature branch tags you
create.  Try to also make the branch tag descriptive of the purpose of
the branch.

One big advantage of a feature branch is that any Developer may commit
changes to a feature branch without all the publication, review, and
approval overhead required when committing patches to the HEAD or
stable branches.  On the feature branches you can go through multiple
revisions reasonably quickly and spend the administrative overhead
only at the end when it is time to apply the finished product to the
official branches.

~ What other things does a maintainer do?

The tasks of fixing bugs and approving and committing patches to the
official source code of Tcl and Tk are the core tasks that maintainers
perform.  That's all the job actually requires.

You will probably want to keep an eye on the TCT's plans for Tcl/Tk
development as well.  If a TIP proposes a new feature in your area, it
is in your interest to know about it, and propose revisions and
improvements to it.  Ultimately you will be asked to approve the patch
that implements the new feature, and then you will be expected to
maintain it, so if you have concerns about a proposal, it's best to
make them known early.  TCT members will probably ask your opinion on
TIPs that propose changes to your area for this reason.

~ Comments

Please add your comments here.

   > Well, since I drafted this SourceForge has replaced the
     Bug Tracker and Patch Manager with a ''Tracker''.  This
     TIP ''really'' needs revision now.

~ Copyright

This document has been placed in the public domain.
Deleted tip/29.tip.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467



















































































































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TIP:            29
Title:          Allow array syntax for Tcl lists
Version:        $Revision: 1.7 $
Author:         Kevin Kenny <[email protected]>
Author:         Donal K. Fellows <[email protected]>
State:          Rejected
Type:           Project
Vote:           Done
Created:        07-Mar-2001
Post-History:   
Discussions-To: news:comp.lang.tcl,mailto:[email protected]
Tcl-Version:    9.0

~ Abstract

Most popular programming languages provide some sort of indexed array
construct, where array subscripts are integers.  Tcl's lists are, in
fact, arrays, but the existing syntax obscures the fact.  Moreover,
the existing list commands make it difficult to manipulate lists as
arrays without running into peculiar performance issues.  This TIP
proposes that the syntax of ''variableName(value)'' be extended to
function as an array selector if ''variableName'' designates a list.
This change is upward compatible with existing Tcl scripts, because
the proposed syntax results in a runtime error in every extant Tcl
release.

~ Rationale

The implementation of lists in Tcl has evolved far beyond the original
conception.  While lists were originally conceived to be strings with
a particular syntax that allowed them to be parsed as lists, the
internal representation of a list is now an array of pointers to
''Tcl_Obj'' structures.

Tcl programmers, for the most part, have not taken advantage of this
evolution.  Code that uses hash tables for the purpose is still
extremely common.  Moreover, it is difficult to update lists in place,
even if their internal representations are known not to be shared.
One example of this difficulty is seen in the discussions
(http://purl.org/thecliff/tcl/wiki/941) of how best to shuffle a list
of items.  The discussion began with a na�ve implementation of Jon
Bentley's method of performing random swaps:

|  proc shuffle1 { list } {
|      set n [llength $list]
|      for { set i 0 } { $i < $n } { incr i } {
|          set j [expr {int(rand()*$n)}]
|          set temp [lindex $list $j]
|          set list [lreplace $list $j $j [lindex $list $i]]
|          set list [lreplace $list $i $i $temp]
|      }
|      return $list
|  }

Aside from the fact that the syntax obscures what the program is
doing, the implementation suffers from an obscure performance problem.
When the ''lreplace'' calls in the ''shuffle1'' procedure are
executed, the internal representation of ''list'' has two references:
the value of the variable, and the parameter passed to ''lreplace''.
The multiple references force ''lreplace'' to copy the list, leading
to quadratic performance when large lists are shuffled.

It is possible, albeit difficult, to alleviate this problem by careful
management of the lifetime of ''Tcl_Obj'' structures, but this change
complicates the code.  The simplest way to fix the performance is
probably to use Donal Fellows's implementation of the ''K''
combinator:

| proc K { x y } { set x }

which allows the caller of ''lreplace'' to extract the value of
''list'', change the value of ''list'' so that the extracted value is
unshared, and then pass the extracted value as a parameter to
''lreplace:''

|  proc shuffle1a { list } {
|      set n [llength $list]
|      for { set i 0 } { $i < $n } { incr i } {
|          set j [expr {int(rand()*$n)}]
|          set temp1 [lindex $list $j]
|          set temp2 [lindex $list $i]
|          set list [lreplace [K $list [set list {}]] $j $j $temp2]
|          set list [lreplace [K $list [set list {}]] $i $i $temp1]
|      }
|      return $list
|  }

Now the performance of the code is ''O(n)'' where ''n'' is the length
of the list, but the programmer's intent has been seriously obscured!

These drawbacks have led prominent individuals such as Richard
Stallman (http://www.vanderburg.org/Tcl/war/0000.html) to assert that
Tcl lacks arrays.

''This proposal includes the absolute minimum of functionality needed
to provide array-style indexing for variables containing Tcl list
objects.''  The reason for this limitation is that omitted
functionality can be added later without breaking existing scripts.
On the other hand, ill-considered extensions may turn into something
that we're doomed to support forever.

~ Specification

This TIP's proposed change can be stated succinctly:

 > Wherever the notation ''a(x)'' may be used to refer to an array
   element in the language, allow it also to refer to an element of a
   list, provided that the variable ''a'' is scalar and the value
   ''x'' is an index suitable for the ''lindex'' command.

   ''Exception:'' Traces, ''unset'' and ''upvar'' calls designating
   individual list elements shall not be supported.  (As a consequence
   of this rule, list elements may also not appear as linked variables
   in C code, implying that they also cannot appear as ''-variable''
   or ''-textvariable'' options on Tk widgets.)

Note that this change is backward compatible with existing Tcl
scripts!  If a notation like ''a(x)'' is used to refer to a scalar
variable in today's Tcl, the result is an error:

| % set a [list foo bar grill]
| foo bar grill
| % set a(2)
| can't read "a(2)": variable isn't array
| % puts $a(2)
| can't read "a(2)": variable isn't array
| % set a(2) zot
| can't set "a(2)": variable isn't array

The default behavior, if ''a'' is not set, and a script executes

| set a(2) zot

will still be to create an associative array.  If a script wishes to
perform such actions on a list, it will be necessary first to
initialize the variable:

| set a [list]
| set a(0) foo

Note that in the example above, there is no requirement that the
internal representation of ''a'' be a list; the line,

| set a [list]

could have been replaced with

| set a {}

with the only impact being the run-time cost of shimmering the empty
string into an empty list.  Nowhere does this proposal introduce
behavior that depends on a specific internal representation for any
variable.

This proposal the syntax of the subscript shall be precisely those
values that are accepted as the second argument to the ''lindex'' command.
In other words, the subscript may be an integer ''N'', or the string
''end'' or ''end-N''.  The value of ''N'' may not be less than zero
nor greater than nor equal to the length of the list on any usage that
reads a list element.  

A usage that writes a list element may use an integer equal to
 the length of the list, or the string ''end+1'', to designate
the element one past the end.  In other words,

|  set a(end+1) foo

will have the same effect as:

|  lappend a foo

With the proposed change in syntax, the procedure to shuffle a list
becomes much more straightforward:

|  proc shuffle1 { list } {
|      set n [llength $list]
|      for { set i 0 } { $i < $n } { incr i } {
|          set j [expr {int(rand()*$n)}]
|          set temp $list($j)
|          set list($j) $list($i)
|          set list($i) $temp
|      }
|      return $list
|  }

The given implementation copies the list only once, the first time
that the line:

|          set list($j) $list($i)

is executed.  Thereafter, the list is an unshared object, and the
replacements are performed in place.

It shall be illegal to pass a list element as the parameter to
''upvar;'' that is, the following usage:

|  proc increment { varName } {
|      upvar 1 $varName v
|      incr v
|  }
|  set x [list 1 2 3]
|  increment x(0)

will ''not'' be supported.  However, the commoner form:

|  proc incrementElement { arrayName index } {
|      upvar 1 $arrayName array
|      incr array($index)
|  }
|  set x [list 1 2 3]
|  incrementElement x 0

will, of course, work as expected.

~ Discussion

Several reviewers expressed concern about the reuse of array syntax.
In particular, the alternative syntax $a<$element> was proposed
repeatedly.  Alas, there is no good alternative syntax that will not
break at least some existing scripts.  The proposed syntax using
angle-brackets is a poor choice, because Tcl scripts that generate
Web pages frequently have code like:

|  puts "<$tag>$text</$tag>

that would be broken horribly by such a change.

There are several obvious extensions to the proposal that are not
addressed, and these omissions are intentional.

   * The proposal makes no attempt to deal with multiple subscripts
     as a means of accessing nested lists.

Use of multiple subscripts is closely related to the withdrawn [22]
(which the author of this TIP intends to revive).  If the related TIP
is accepted, the syntax for the subscript could readily be expanded
so that it could be a Tcl list giving the subscripts in lexicographic
sequence.  For example

| set a(2 3) foo

could be used to set the fourth element of the third sublist.

   * The proposal allows the ''set'' command (or any other use of
     ''Tcl_SetVar2Ex'') to set only the elements that are in the list
     already plus the one one beyond the end.

Tcl lists are fundamentally dense arrays.  Allowing non-contiguous
elements, that is, sparse arrays, is a fundamental change to their
semantics.  Such a change is not contemplated at this time.

   * The proposal does not allow the ''unset'' command (or any
     other command that arrives at ''Tcl_UnsetVar2'') to delete members
     of a list.

Earlier versions of the proposal had proposed to permit:

|  unset a([expr { [llength $a] - 1}])

or equivalently:

|  unset a(end)

to reduce the length of the list by one.  In subsequent discussions,
the reviewers found it distasteful that the proposed syntax did not
permit unsetting interior elements of a list.  Alas, the discussion
did not arrive at a consensus on what the precise semantics of such
an operation ought to be.  Some reviewers favored attempting to emulate
sparse arrays (again, a fundamental change to the semantics of
Tcl lists that is not contemplated at this time).  Others preferred
the semantics of shifting the remaining elements, so that

|   unset a($n)

would always be equivalent to

|   set a [lreplace $a $n $n]

except for performance.  Both camps found it overly restrictive to
limit the semantics of ''unset'' to those of the original proposal.
Because the two groups failed to achieve a consensus, the author of
this TIP finds it prudent to forbid ''unset'' altogether in the
initial implementation.

   * The ''array'' command continues to operate only on associative
     arrays.

Lists are a simple enough structure that the full power of the
''array'' command is not required to deal with them, and having it
work on lists as well as arrays seems like needless effort.  Moreover,
existing code may well depend on a combination of ''[array exists]''
and ''[info exists]'' to distinguish associative arrays from scalar
variables (including lists).

   * The ''upvar'' command cannot address individual list elements.

Extending the syntax in this fashion would make ''upvar'' more
consistent in its behavior, but appears to be expensive, in terms of
both performance (tracking down the linked references if a list is
rebuilt) and the effort required for implementation (the author of
this TIP is unlikely to have the time required to implement the
necessary changes to ''struct Var'' and the associated code).

   * No traces on list elements shall be supported.  List elements
     cannot function as linked variables in C code.

The original proposal had specified how write and unset, but not read,
traces could be implemented.  The original proposed functionality is
described in the Appendix.  The author of this TIP had proposed it
primarily so that list elements could function as linked variables
(for instance, in the ''-variable'' and ''-textvariable'' options
of Tk widgets).

Once again, this part of the original proposal failed for lack of
consensus among the reviewers.  Some felt that supporting read traces
in one context but not another would be overly confusing.  Moreover,
the proposal as written would cause write traces on the elements to fire
if the internal representation of a variable shimmered between a list
and something else.  Some reviewers found the excess trace callbacks
to be objectionable.  

At least one reviewer proposed a separate ''trace add element'' syntax
for list-element traces.  This syntax would address some of the
concerns about the lack of read traces (there's no reason that ''trace
add element'' should function the same as ''trace add variable'').
Alas, it would not address the problem of linked variables, which was
the main reason for having the traces in the first place.

Given the lack of consensus, the author of this TIP finds it prudent
to withdraw or postpone this portion of the proposal.

~ See Also

[22] - withdrawn.

~ Reference Implementation

No reference implementation has yet been developed; the author of this
TIP wishes to solicit the opinions of the Tcl community before
spending a lot of time implementing a possibly bad idea.

~ Change history

''12 March 2001:'' Added detailed discussion of the specific subscript
ranges supported by read, write and unset operations.  Changed the discussion
to reject the alternative of padding an array when setting an index beyond
the end.  Added discussion of the details of write and unset traces, and
rejecting read traces as being infeasible to implement.  Clarified the
example of creating an empty list so as to avoid any misapprehension that
these changes depend on list variables' having a particular representation
at any given time; in fact, every detail of this proposal is tolerant of
shimmering.

''13 March 2001:'' Fixed a copy-and-paste error in the 'incrementElement'
example, and added to the discussion the fact that all operations will
throw errors in the event of a malformed list.

''30 March 2001:'' Revised yet again, in an attempt to remove as
much controversial functionality as possible and reduce the TIP to the
minimum useful subset, on the grounds that it is prudent to avoid
supporting functionality that may later prove ill-considered.

~ Summary of objections

''DeJong,'' ''English'' (non-voting), ''Flynt'' (non-voting),
''Harrison,'' ''Ingham,'' ''Lehenbauer,'' ''Polster,'' (non-voting),
''Porter,'' and ''Sofer'' (non-voting), expressed concern that the
proposed syntax is confusing, since the target object could be either
an associative array or a linear array (that is, a Tcl list).
These objections varied in stridency from "yes, it is a risk, and
I'm prepared to accept it," to "this will just be too confusing, and I
can't countenance this proposal."

''Hobbs'' found the original proposal's omission of reverse indexing
distasteful.  The current version of the proposal embraces his
suggested change.

''Cuthbert'' (non-voting), ''Hobbs'', and ''Porter'' expressed concern
over the semantics of ''unset.'' Since consensus was not achieved, the
current version of the proposal defers implementation of ''unset.''

Several reviewers, most notably ''Ousterhout,'' found the proposed
''trace'' semantics distasteful.  The current version of the proposal
eliminates ''trace'' on list elements.

Several reviewers appeared to labor under the misconception that this
TIP introduces behavior that is dependent at run time upon the
internal representation of a Tcl object.  It does not; it is tolerant
of shimmering in all cases.

Several reviewers objected to the proposal on the grounds that it does
not specify a general object system and how such a system would allow
for generic containers with array syntax.  The author's intention in
writing it was not to propose such a system, but only to propose a
small piece of syntactic sugar, implementable here and now, that is
compatible with that broader vision.

~ Appendix: Possible implementation of read and unset traces.

The original proposal contained the following language, which could
be used as a guide if traces on list elements are contemplated at a
future time.

Write and unset traces on list elements shall be supported; it shall
be permissible to write:

|    trace add variable x(1) write writeCallback

or

|    trace add variable x(1) unset unsetCallback

The ''write'' callback shall be invoked whenever the given list
element changes value; the ''unset'' callback shall be invoked
whenever the variable is unset or when its length shrinks to the point
that it no longer has a member with the given index.

Read traces on list elements shall ''not'' be supported.  It is
too difficult at this point to define what their semantics should be.
For instance, if a program executes the following code:

|   trace add variable x(0) read readCallback
|   set x [list foo bar grill]
|   set y [string range $x 4 end]

should the callback fire?  By one argument, the program has not
read element zero of the list; by another, using the list as a string
has read every element, and all read traces should fire.  In any case,
the read trace on a variable fires before its usage is known; it appears
impossible in existing code to implement selective read tracing on list
elements.

The implementation of write and unset traces on list elements will be
done by establishing a C-level write trace on the variable as a whole.
The client data of the trace will designate a structure containing the
ordinal number of the element being traced, and a ''Tcl_Obj'' pointer
designating its old value.  The reference count of the ''Tcl_Obj''
will be incremented when this pointer is stored.  Note that this
increment operation makes the object shared.  Any change to the
designated element will thus need to copy the object.

When the write trace fires, the list representation of the variable
will be extracted, reconstituting it from the string representation if
necessary.  If extracting the list representation fails, the trace
will be considered to have failed as well, and the trace callback will
return ''TCL_ERROR''.  If extracting the list representation succeeds,
the list length will be compared with the ordinal number of the
element being traced.  If the element number is no longer within the
list, an unset trace fires if one exists.  If the element number is
within the list, the two ''Tcl_Obj'' pointers are compared.  If they
are identical, the list element in question is unchanged, and nothing
need be done.  Otherwise, the write trace fires.  

This behavior is conservative in that an operation that spoils the
list representation of the object is considered to have written every
element of the list.  This rule is consistent with the rule that write
traces on ordinary Tcl variables fire whenever the variable is set,
even if it is being set to an identical value.

In any event, after the conclusion of a trace callback, the saved
Tcl_Obj will have its reference count decremented and be replaced with
the current element of the list (with reference count appropriately
incremented, of course).

~ Copyright

This document has been placed in the public domain.
Changes to tip/3.tip.
1
2
3

4
5
6
7
8
9
10
1
2

3
4
5
6
7
8
9
10


-
+







TIP:            3
Title:          TIP Format
Version:        $Revision: 1.3 $
Version:        $Revision: 1.2 $
Author:         Andreas Kupries <[email protected]>
Author:         Donal K. Fellows <[email protected]>
State:          Accepted
Type:           Process
Vote:           Done
Created:        14-Sep-2000
Post-History:
132
133
134
135
136
137
138
139

140
141
142
143
144
145
146
132
133
134
135
136
137
138

139
140
141
142
143
144
145
146







-
+








   Title:
	Defines the title of the document using plain text. May change
	during the discussion and review phases.

   Version:
	Specifies the version of the document.  Usually something like
	$Revision: 1.3 $. (Initially $Revision: 1.3 $ should be used, which
	$Revision: 1.2 $. (Initially $Revision: 1.2 $ should be used, which
	is then changed by the version control to contain the actual
	revision number.

   Author:
	Contact information (email address) for each author. The email
	address has to contain the real name of the author.  If there
	are multiple authors of the document, this header may occur
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
471
472
473
474
475
476
477






















478
479
480
481
482
483
484
485
486
487
488
489
490
491






















492
493
494
495
496







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-














-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-





|
|#index: long
|
|#image:3example This is a test caption
|
|This is an example long TIP reference tip:3 that should be expanded in
|a renderer-specific way...
|
|This is an example non-reference - ''index[[3]]'' - that should not
|be rendered as a link (to this document or anywhere else) at all.
|Note that the dashes in the previous sentence (with whitespace on
|each side) are candidates for rendering as long dashes (em-dashes) on
|output-media which support this.
|
| Supported URLs: should be http, https, mailto, news, newsrc, ftp and
|   gopher.  Test here...
|
| > HTTP URL - http://purl.org/thecliff/tcl/wiki/
|
| > HTTPS URL - https://sourceforge.net/
|
| > FTP URL - ftp://src.doc.ic.ac.uk/packages/tcl/tcl/
|
| > NEWS URL - news:comp.lang.tcl
|
| > MAILTO URL - mailto:[email protected]?subject=TIP3
| 
| > Others (might not be valid links!) - gopher://info.mcc.ac.uk,
|   newsrc:2845823825

and here is the rendered result.

#index:

#index:short

#index: long

#image:3example This is a test caption

This is an example long TIP reference tip:3 that should be expanded in
a renderer-specific way...

This is an example non-reference - ''index[[3]]'' - that should not
be rendered as a link (to this document or anywhere else) at all.
Note that the dashes in the previous sentence (with whitespace on
each side) are candidates for rendering as long dashes (em-dashes) on
output-media which support this.

 Supported URLs: should be http, https, mailto, news, newsrc, ftp and
   gopher.  Test here...

 > HTTP URL - http://purl.org/thecliff/tcl/wiki/

 > HTTPS URL - https://sourceforge.net/

 > FTP URL - ftp://src.doc.ic.ac.uk/packages/tcl/tcl/

 > NEWS URL - news:comp.lang.tcl

 > MAILTO URL - mailto:[email protected]?subject=TIP3
 
 > Others (might not be valid links!) - gopher://info.mcc.ac.uk,
   newsrc:2845823825

----

~ Copyright

This document has been placed in the public domain.
Deleted tip/30.tip.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233









































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TIP:            30
Title:          Tk Toolkit Maintainer Assignments
Version:        $Revision: 1.27 $
Author:         Don Porter <[email protected]>
Author:         Donal K. Fellows <[email protected]>
Author:         Jan Nijtmans <[email protected]>
Author:         Todd M. Helfter <[email protected]>
Author:         Chengye Mao <[email protected]>
Author:         George B. Smith <[email protected]>
Author:         Miguel Ba��n <[email protected]>
Author:         Daniel Steffen <[email protected]>
Author:         Peter Spjuth <[email protected]>
Author:         Jeff Hobbs <[email protected]>
State:          Draft
Type:           Informative
Vote:           Pending
Created:        09-Mar-2001
Post-History:   

~ Abstract

This document keeps a record of who maintains each functional area
of Tk ([23]).

~ Assignments

Listed below are Tk's 86 functional units, in the same order as in
[23].  See [23] for the precise definition of what code belongs to
what area, and how maintainers designate their support for
platform-specific portions of the code.  The area names listed below
are also the Categories in the SourceForge Tracker for the Tk Toolkit
(http://sourceforge.net/tracker/?group_id=12997).

For each of Tk's functional units, the following maintainers are 
assigned:

   1. ''Bindings'' - Jeff Hobbs <[email protected]>

   2. ''Appearance'' - Jeff Hobbs <[email protected]>

   3. ''[*button] and [label]'' - Allen Flick <[email protected]>, Jeff Hobbs <[email protected]>, Daniel Steffen <[email protected]> (Mac)

   4. ''Canvas Basics'' - Jeff Hobbs <[email protected]>, Jan Nijtmans <[email protected]>

   5. ''Canvas Items'' - Jeff Hobbs <[email protected]>, Jan Nijtmans <[email protected]>

   6. ''Canvas PostScript'' - Jeff Hobbs <[email protected]>

   7. ''[entry]'' - Allen Flick <[email protected]>, Jeff Hobbs <[email protected]>

   8. ''[frame] and [toplevel]'' - Jeff Hobbs <[email protected]>,
	Peter Spjuth <[email protected]>

   9. ''[listbox]'' - Allen Flick <[email protected]>, Jeff Hobbs <[email protected]>

   10. ''Generic Menus'' - Jeff Hobbs <[email protected]>, Todd Helfter <[email protected]>

   11. ''Mac Menus'' - George B. Smith <[email protected]>, Daniel Steffen <[email protected]>

   12. ''Unix Menus'' - Jeff Hobbs <[email protected]>, Todd Helfter <[email protected]>

   13. ''Win Menus'' - Jeff Hobbs <[email protected]>, Todd Helfter <[email protected]>

   14. ''[message]'' - Jeff Hobbs <[email protected]>

   15. ''[scale]'' - Jeff Hobbs <[email protected]>, Daniel Steffen <[email protected]> (Mac)

   16. ''[scrollbar]'' - Jeff Hobbs <[email protected]>, Daniel Steffen <[email protected]> (Mac)

   17. ''[spinbox]'' - Jeff Hobbs <[email protected]>

   18. ''[text]'' - Jeff Hobbs <[email protected]>

   19. ''Menubars (obsolete)'' - Jeff Hobbs <[email protected]>

   20. ''[tk_optionMenu]'' - Jeff Hobbs <[email protected]>

   21. ''Option Parsing'' - Jeff Hobbs <[email protected]>, Daniel Steffen <[email protected]> (Mac)

   22. ''Relief'' - Jeff Hobbs <[email protected]>, Fr�d�ric Bonnet <[email protected]>

   23. ''Built-in Bitmaps'' - Jeff Hobbs <[email protected]>, Jan Nijtmans <[email protected]>, Daniel Steffen <[email protected]> (Mac)

   24. ''Conversions From String'' - Jeff Hobbs <[email protected]>

   25. ''Objects'' -  Jeff Hobbs <[email protected]>

   26. ''Utility Functions'' - Jeff Hobbs <[email protected]>

   27. ''Colormaps and Visuals'' - Jeff Hobbs <[email protected]>

   28. ''Color Names'' - Jeff Hobbs <[email protected]>, Daniel Steffen <[email protected]> (Mac)

   29. ''Cursor Names'' - Jeff Hobbs <[email protected]>, Daniel Steffen <[email protected]> (Mac)

   30. ''Key Symbols'' - Jeff Hobbs <[email protected]>, Daniel Steffen <[email protected]> (Mac)

   31. ''Generic Dialog Support'' - Donal K. Fellows <[email protected]>, Jeff Hobbs <[email protected]>

   32. ''[tk_chooseColor]'' - Donal K. Fellows <[email protected]> ''(Unix)'', Jeff Hobbs <[email protected]>

   33. ''[tk_dialog]'' - Donal K. Fellows <[email protected]> ''(Unix)'', Jeff Hobbs <[email protected]>, Daniel Steffen <[email protected]> (Mac)

   34. ''[tk_chooseDirectory]'' - Donal K. Fellows <[email protected]> ''(Unix)'', Jeff Hobbs <[email protected]>

   35. ''[tk_get*File]'' - Donal K. Fellows <[email protected]> ''(Unix)'', Jeff Hobbs <[email protected]>

   36. ''[tk_messageBox]'' - Donal K. Fellows <[email protected]> ''(Unix)'', Jeff Hobbs <[email protected]>

   37. ''Image Basics'' - Jan Nijtmans <[email protected]>

   38. ''Bitmap Images'' - Jan Nijtmans <[email protected]>,
			   Kevin Griffin <[email protected]>

   39. ''Photo Images'' - Jan Nijtmans <[email protected]>

   40. ''Photo Image|GIF'' - Jan Nijtmans <[email protected]>

   41. ''Photo Image|PPM'' - Jan Nijtmans <[email protected]>

   42. ''Generic Fonts'' - Jeff Hobbs <[email protected]>

   43. ''Mac Fonts'' - George B. Smith <[email protected]>, Daniel Steffen <[email protected]>

   44. ''Unix Fonts'' - Jeff Hobbs <[email protected]>

   45. ''Win Fonts'' - Jeff Hobbs <[email protected]>

   46. ''Geometry Management'' - Jeff Hobbs <[email protected]>, Chengye Mao <[email protected]>

   47. ''[grid]'' - Jeff Hobbs <[email protected]>, Peter Spjuth <[email protected]>

   48. ''[pack]'' - Jeff Hobbs <[email protected]>, Peter Spjuth <[email protected]>

   49. ''[place]'' - Jeff Hobbs <[email protected]>, Peter Spjuth <[email protected]>

   50. ''[clipboard]'' - Jeff Hobbs <[email protected]>
		         Joe English <[email protected]> (Unix), Daniel Steffen <[email protected]> (Mac)

   51. ''[selection]'' - Jeff Hobbs <[email protected]>,
		         Joe English <[email protected]> (Unix)

   52. ''[console]'' - Jeff Hobbs <[email protected]>, Chengye Mao <[email protected]>

   53. ''[focus]'' - Jeff Hobbs <[email protected]>

   54. ''[grab]'' - Jeff Hobbs <[email protected]>

   55. ''[option]'' - Allen Flick <[email protected]>, Jeff Hobbs <[email protected]>

   56. ''[send]'' - Allen Flick <[email protected]>, Jeff Hobbs <[email protected]>, Daniel Steffen <[email protected]> (Mac)

   57. ''[tk_focus*]'' - Jeff Hobbs <[email protected]>

   58. ''[tk_setPalette]'' - Jeff Hobbs <[email protected]>

   59. ''Safe Tk'' - Jeff Hobbs <[email protected]>

   60. ''Geometry Functions'' - Jeff Hobbs <[email protected]>, Chengye Mao <[email protected]>

   61. ''Tk_Win Functions'' - Jeff Hobbs <[email protected]>

   62. ''Graphic Contexts'' - Jeff Hobbs <[email protected]>

   63. ''Generic Window Operations'' - Jeff Hobbs <[email protected]>

   64. ''Mac Window Operations'' - George B. Smith <[email protected]>, Daniel Steffen <[email protected]>

   65. ''Unix Window Operations'' - Jeff Hobbs <[email protected]>,
				    Joe English <[email protected]>

   66. ''Win Window Operations'' - Jeff Hobbs <[email protected]>, Chengye Mao <[email protected]>

   67. ''Events'' - Jeff Hobbs <[email protected]>

   68. ''Event Loop'' - Jeff Hobbs <[email protected]>, Jan Nijtmans <[email protected]>

   69. ''Error Handling'' - Jeff Hobbs <[email protected]>

   70. ''Atoms'' - Jeff Hobbs <[email protected]>

   71. ''Argv Parsing'' - Jeff Hobbs <[email protected]>

   72. ''Application Embedding'' - Daniel Steffen <[email protected]> (Mac)

   73. ''wish'' - Daniel Steffen <[email protected]> (Mac)

   74. ''Mac DND Tclets'' - Daniel Steffen <[email protected]>

   75. ''Widget Tour'' - Donal K. Fellows <[email protected]>, Jeff Hobbs <[email protected]>

   76. ''Square Demo'' - Jeff Hobbs <[email protected]>

   77. ''Other Demos'' - Donal K. Fellows <[email protected]>, Jeff Hobbs <[email protected]>

   78. ''L10N'' - Jan Nijtmans <[email protected]>, Miguel Ba��n <[email protected]>

   79. ''Release Notes'' - Jeff Hobbs <[email protected]>

   80. ''Portability'' - Jeff Hobbs <[email protected]>

   81. ''X11 Emulation'' - Jeff Hobbs <[email protected]>

   82. ''Mac Build'' - George B. Smith <[email protected]>, Daniel Steffen <[email protected]>

   83. ''Unix Build'' - Jeff Hobbs <[email protected]>,
			Mo DeJong <[email protected]>,
			Lloyd Lim <[email protected]>

   84. ''Win Build'' - Jeff Hobbs <[email protected]>,
			Mo DeJong <[email protected]>

   85. ''Test Tools'' - Allen Flick <[email protected]>, Jeff Hobbs <[email protected]>, Daniel Steffen <[email protected]> (Mac)

   86. ''Logos'' - Jeff Hobbs <[email protected]>

~ General Categories

The  following categories in Tk's SourceForge Tracker do not refer to any
specific portion of Tk.  Reports in these categories should be mapped to
categories corresponding to a maintained area of Tk, when seeking the
appropriate maintainer:

   1. ''Other'' - Reports that span multiple categories.

~ Areas Without Maintainers

Those funcational areas without a maintainer are maintained by the Tcl 
Core Team with each change requiring TYANNOTT review.

~ Copyright

This document has been placed in the public domain.
Deleted tip/31.tip.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146


















































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TIP:            31
Title:          CVS tags in the Tcl and Tk repositories
Version:        $Revision: 1.6 $
Author:         Don Porter <[email protected]>
Author:         miguel sofer <[email protected]>
Author:         Jeff Hobbs <[email protected]>
Author:         Kevin Kenny <[email protected]>
State:          Draft
Type:           Informative
Vote:           Pending
Created:        12-Mar-2001
Post-History:   

~ Abstract

This document keeps a record of the CVS tags used in the Tcl and Tk
repositories and their meanings.

~ Background

CVS uses tags to collectively label a particular set of revisions of a
particular set of files.  With a tag, one may easily request all the
revisions of all the files that correspond to something meaningful,
such as an official release of a project.

There are two kinds of tags provided by CVS.  First is the release tag
that simply marks a set of revisions as belonging together as a unit.
Each release of a project should be tagged with a release tag.  Other
development milestones may also receive a release tag.  Release tags
are useful for marking any point in development that will be useful to
return to or compare against.

The second kind of tag is a branch tag.  It does not mark a single
revision of a file, but an entire branch of development of a file.
Branch tags are the means by which different working directories can
track different branches of development.

A tag may be used in a CVS repository only once, so we must keep track
of what tags have already been used, and what they mean.  The
remaining sections of this TIP record the tags in use.  This TIP
should be kept up to date by adding any new tags here as they are
added to the CVS repository.

~ Release Tags

The following tags in the Tcl and Tk CVS repositories correspond to
the following releases of Tcl/Tk:

   * core-8-3-3 - Tcl/Tk 8.3.3

   * core-8-4-a2 - Tcl/Tk 8.4a2

   * core-8-4-a1 - Tcl/Tk 8.4a1

   * core-8-3-2 - Tcl/Tk 8.3.2

   * core-8-3-1 - Tcl/Tk 8.3.1

   * core-8-3-0 - Tcl/Tk 8.3.0

   * core-8-3-b2 - Tcl/Tk 8.3b2

   * core-8-3-b1 - Tcl/Tk 8.3b1

   * core-8-2-3 - Tcl/Tk 8.2.3

   * core-8-2-2 - Tcl/Tk 8.2.2

   * core-8-2-1 - Tcl/Tk 8.2.1

   * core-8-2-0 - Tcl/Tk 8.2.0

   * core-8-2-b3 - Tcl/Tk 8.2b3

   * core-8-2-b2 - Tcl/Tk 8.2b2

   * core-8-2-b1 - Tcl/Tk 8.2b1

   * core-8-1-1 - Tcl/Tk 8.1.1

   * core-8-1-0 - Tcl/Tk 8.1.0

   * core-8-1-b3 - Tcl/Tk 8.1b3

   * core-8-1-b2 - Tcl/Tk 8.1b2

   * core-8-1-b1 - Tcl/Tk 8.1b1

   * core-8-0-5 - Tcl/Tk 8.0.5

   * core-8-0-4 - Tcl/Tk 8.0.4

   * core-8-0-3 - Tcl/Tk 8.0.3

   * core-8-0-2 - Tcl/Tk 8.0p2

~ Branch Tags - Official Development

The following branch tags label branches of development from which
releases of Tcl/Tk are generated:

   * HEAD - current development of new features; spawns 8.4aX
     releases.

   * core-8-3-1-branch - bug fix branch; spawns 8.3.X releases.

~ Branch Tags - Features

The following branch tags label branches on which features are being
devloped and tested.  No releases of Tcl/Tk will be spawned from these
branches.  As the features mature, they will be merged onto the HEAD
branch, or they may be rejected.

   * core-8-4-win-speedup (Tk) - Work on improving performance of Tk
     on the Windows platforms.

   * kennykb-tip-22-33 (Tcl) - Work on implementing the changes
     described in TIP's #22 and #33.

   * msofer-bcEngine (Tcl) - Work on improving performance of the bytecode engine.

~ Dead Branches

The following branch tags label branches that are no longer being
developed.  Some are old official branches from which releases are no
longer being spawned.  Others are feature development branches that
have been merged into an official branch, or rejected.

   * dgp-privates-into-namespace (Tk) - Work on moving Tk's private
     commands and variables into the ::tk namespace and its children.
     Merged into Tk 8.4a3.

   * core-8-3-1-io-rewrite (Tcl) - Work rewriting Tcl's IO Channels to
     correct problems with the implementation of stacked channels.
     Merged into Tcl 8.3.2 and Tcl 8.4a2.

   * core-8-2-1-branch - Spawned Tcl/Tk 8.2.X releases.

   * core-8-1-branch-old - Spawned Tcl/Tk 8.1bX releases.

   * dev-stubs-branch, dev-8-1-stubs-branch - Two branches on which
     the stubs interfaces were developed.  Merged into Tcl 8.1.

~ Copyright

This document has been placed in the public domain.
Deleted tip/32.tip.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TIP:            32
Title:          Add Tcl_Obj support to traces
Version:        $Revision: 1.3 $
Author:         David Cuthbert <[email protected]>
Author:         Kevin Kenny <[email protected]>
State:          Draft
Type:           Project
Vote:           Pending
Created:        23-Mar-2001
Post-History:   
Discussions-To: news:comp.lang.tcl
Keywords:       trace,Tcl_Obj
Tcl-Version:    8.4a2

~ Abstract

This document proposes to add Tcl_Obj support for trace procedures written
in C.

~ Rationale

The ''Tcl_Obj'' system was introduced in version 8.0, making
computations (potentially) much more efficient by eliminating many
type conversions to and from strings.  However, the trace API
continues to require character strings in both command and variable
traces.

~ Specification

Add the following functions to the Tcl core:

 * Tcl_Trace ''Tcl_CreateObjTrace''(interp, level, objProc,
   clientData)

 > ''Tcl_CreateObjTrace'' behaves in the same manner as
   ''Tcl_CreateTrace'', except the trace procedure (objProc) should
   have arguments and result that match type type
   ''Tcl_CmdObjTraceProc'':

|typedef void Tcl_CmdObjTraceProc(
|    ClientData clientData,
|    Tcl_Interp *interp,
|    int level,
|    char *command,
|    Tcl_ObjCmdProc *cmdProc,
|    ClientData cmdClientData,
|    int objc,
|    Tcl_Obj * CONST objv[] );

 > Trace tokens returned by ''Tcl_CreateObjTrace'' can be used in
   ''Tcl_DeleteTrace'' to remove the trace.

 * int ''Tcl_ObjTraceVar2''(interp, part1Ptr, part2Ptr, flags,
   objProc, clientData)

 > ''Tcl_ObjTraceVar2'' behaves in the same manner as
   ''Tcl_TraceVar2'', except the variable name is passed as Tcl_Obj
   pointers (in the same manner as ''Tcl_ObjSetVar2'', q.v.), and the
   trace procedure (objProc) should have arguments and result that
   match the type ''Tcl_VarObjTraceProc'':

|typedef Tcl_Obj *Tcl_VarObjTraceProc(
|    ClientData clientData,
|    Tcl_Interp *interp,
|    Tcl_Obj *part1Ptr,
|    Tcl_Obj *part2Ptr,
|    int flags );

 > Under normal conditions, the trace procedure should return NULL,
   indicating successful completion.  If objProc returns a value other
   than NULL it signifies that an error occurred.  Upon return,
   the reference count of the Tcl_Obj should be at least one;
   ownership of this reference is transferred to the Tcl interpreter.

 * void ''Tcl_ObjUntraceVar2''(interp, part1Ptr, part2Ptr, flags,
   objProc, clientData)

 > ''Tcl_ObjUntraceVar2'' behaves in the same manner as
   ''Tcl_UntraceVar2'', except it is used to remove trace procedures
   registered with ''Tcl_ObjTraceVar2''.

 * ClientData ''Tcl_ObjVarTraceInfo2''(interp, part1Ptr, part2Ptr,
   flags, objProc, prevClientData)

 > ''Tcl_ObjVarTraceInfo2'' behaves in the same manner as
   ''Tcl_VarTraceInfo2'', except it is used to iterate through trace
   procedures registered with ''Tcl_ObjTraceVar2''.

~ Change History

30 March 2001 - Changed return value of objProc to a Tcl_Obj * instead
of int (and using the interpreter result to indicate an error).  This
is more consistent with the current behavior (but without the bug).  -dac

~ See Also

Tcl manual pages ''Tcl_TraceVar'' and ''Tcl_CreateTrace''.

~ Copyright

Copyright � 2000 by David Cuthbert.  Distribution in whole or part,
with or without annotations, is unlimited.

~ Comments

Kevin Kenny (2 April 2001):

This proposal is detailing functionality that I've wanted for
quite some time.  Given, however, that it allows us to make a
partial break with the past, I'd like to make some minor changes
to ''Tcl_CmdObjTraceProc.''

In place of the type signature,

|  typedef void Tcl_CmdObjTraceProc(
|      ClientData clientData,
|      Tcl_Interp *interp,
|      int level,
|      char *command,
|      Tcl_ObjCmdProc *cmdProc,
|      ClientData cmdClientData,
|      int objc,
|      Tcl_Obj * CONST objv[] );

may I suggest that since the interpreter has the ''Command'' structure
in hand, it simply deliver a ''Tcl_Command'' with the command's
information, in place of the command procedure and client data?
Also, the command name is redundant, since the same information
is present in ''objv[ 0 ]''.

The signature would then be:

|  typedef void Tcl_CmdObjTraceProc(
|      ClientData clientData,  /* Client data from Tcl_CreateObjTrace */
|      Tcl_Interp* interp,     /* Tcl interpreter */
|      int level,              /* Execution level */
|      Tcl_Command cmdInfo,    /* Command information */
|      int objc,               /* Parameter count */
|      Tcl_Obj *CONST objv[]   /* Parameter vector */
|  );

This would allow the trace procedure to do interesting things like
replace the command's ''objCmdProc'' and client data temporarily,
before the interpreter uses them.  I have a profiler that works
that way, using the existing API's.  It's awkward at the moment,
because it needs to use ''Tcl_FindCommand'' to get at the command
object (''Tcl_GetCommandInfo'' would also work in current releases,
but I'm in the position of needing bugward compatibility with 8.0).
It also is a horrible performance drain because of the shimmering
that's needed to support tracing currently, and the fact that
tracing defeats the bytecode compiler.

If this change gets approved, and I can get ''TclpGetTime'' exported,
I'll definitely release the profiler.  (I don't care to release code
that depends on tclInt.h, because I don't want to track APIs
that the maintainers don't consider 'stable'.)

By the way, this change should be easier from a political standpoint
than it was a year ago, when any extension that used this mechanism
was presumably a competitor of the TclPro tools.
Deleted tip/33.tip.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666


























































































































































































































































































































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TIP:            33
Title:          Add 'lset' Command to Assign to List Elements.
Version:        $Revision: 1.11 $
Author:         Kevin Kenny <[email protected]>
State:          Accepted
Type:           Project
Vote:           Done
Created:        15-May-2001
Post-History:   
Discussions-To: news:comp.lang.tcl,mailto:[email protected]
Tcl-Version:    8.4

~ Abstract

Most popular programming languages provide some sort of indexed array
construct, where array subscripts are integers.  Tcl's lists are
implemented internally as indexed arrays, but it is difficult to use
them as such because there is no convenient way to assign to
individual elements.  This TIP proposes a new command, ''lset'', to
rectify this limitation.

~ Rationale

The implementation of lists in Tcl has evolved far beyond the original
conception.  While lists were originally conceived to be strings with
a particular syntax that allowed them to be parsed as lists, the
internal representation of a list is now an array of pointers to
''Tcl_Obj'' structures.

Tcl programmers, for the most part, have not taken advantage of this
evolution.  Code that uses hash tables where linear arrays would be a
more appropriate structure is still extremely common.  Moreover, it is
difficult to update lists in place, even if their internal
representations are known not to be shared.  One example of this
difficulty is seen in the discussions
(http://purl.org/thecliff/tcl/wiki/941)
of how best to shuffle a list of items.  The discussion began with a
na�ve implementation of Jon Bentley's method of performing random
swaps:

|  proc shuffle1 { list } {
|      set n [llength $list]
|      for { set i 0 } { $i < $n } { incr i } {
|          set j [expr {int(rand()*$n)}]
|          set temp [lindex $list $j]
|          set list [lreplace $list $j $j [lindex $list $i]]
|          set list [lreplace $list $i $i $temp]
|      }
|      return $list
|  }

Aside from the fact that the syntax obscures what the program is
doing, the implementation suffers from an obscure performance problem.
When the ''lreplace'' calls in the ''shuffle1'' procedure are
executed, the internal representation of ''list'' has two references:
the value of the variable, and the parameter passed to ''lreplace''.
The multiple references force ''lreplace'' to copy the list, leading
to quadratic performance when large lists are shuffled.

It is possible, albeit difficult, to alleviate this problem by careful
management of the lifetime of ''Tcl_Obj'' structures, but this change
complicates the code.  The simplest way to fix the performance is
probably to use Donal Fellows's implementation of the ''K''
combinator:

| proc K { x y } { set x }

which allows the caller of ''lreplace'' to extract the value of
''list'', change the value of ''list'' so that the extracted value is
unshared, and then pass the extracted value as a parameter to
''lreplace:''

|  proc shuffle1a { list } {
|      set n [llength $list]
|      for { set i 0 } { $i < $n } { incr i } {
|          set j [expr {int(rand()*$n)}]
|          set temp1 [lindex $list $j]
|          set temp2 [lindex $list $i]
|          set list [lreplace [K $list [set list {}]] $j $j $temp2]
|          set list [lreplace [K $list [set list {}]] $i $i $temp1]
|      }
|      return $list
|  }

Now the performance of the code is ''O(n)'' where ''n'' is the length
of the list, but the programmer's intent has been seriously obscured!
Moreover, the performance is still rather poor: Tcl makes an atrocious
showing, for instance, in Doug Bagley's 'Great Computer Language
Shootout' (http://www.bagley.org/~doug/shootout/).

~ Specification

This TIP proposes an 'lset' command with the syntax:

|  lset varName indexList value

or

|  lset varName index1 index2... value

where:

 > ''varName'' is the name of a variable in the caller's scope.

 > If ''objc==4'', then the ''indexList'' parameter is interpreted as
   a list of ''index'' arguments; if ''objc>4'', then the ''index''
   arguments are inline on the command line.

 > In either case, Each ''index'' argument is an index in the content
   of ''varName'' or one of its sublists (see below).  The format of
   ''index'' is either an integer whose value is at least zero and
   less than the length of the corresponding list, or else the literal
   string ''end'', optionally followed with a hyphen and an integer
   whose value is at least zero and less than the length of the
   corresponding list.

 > ''value'' is a value that is to be stored as a list element.

The return value of the command, if successful, is the new value
of ''varName.''

The simplest form of the command:

|  lset varName index value

replaces, in place, the ''index'' element of ''varName'' with the
specified ''value''.  For example, the code:

|  set x {a b c}
|  lset x 1 d

results in ''x'' having the value ''a d c''.  The result, except
for performance considerations and the details of error reporting,
is roughly the same as the Tcl code:

|  proc lset { varName index value } {
|      upvar 1 $varName list
|      set list [lreplace $list $index $index $value]
|      return $list
|  }

except that where the ''lreplace'' command permits indices outside the
existing list elements, the proposed ''lset'' command forbids them.

If multiple ''index'' arguments are supplied to the ''lset'' command,
they refer to successive sublists in a hierarchical fashion.  Thus,

|   lset varName $i $j value

or, equivalently,

|   lset varName [list $i $j] value

asks to change the value of the ''j''th element in the ''i''th sublist
of ''varName''.  Hence, the code:

|   set x {{a b c} {d e f} {g h i}}
|   lset x 1 1 j; # -or- lset x {1 1} j

changes the value of ''x'' to

|   {a b c} {d j f} {g h i}

and the code

|   set y {{{a b} {c d}} {{e f} {g h}}}
|   lset y 1 0 1 i; # -or- lset y {1 0 1} i

changes the value of ''y'' to

|   {{a b} {c d}} {{e i} {g h}}

This notation also dovetails prettily with the extension of the
''lindex'' command proposed in [22].  The command

|   lindex $y 1 0 1; # -or- lindex y {1 0 1}

will extract the element that is set by the command

|   lset $y 1 0 1 $value

The ''lset'' command will throw an error and leave the variable
unchanged if it is presented with fewer than three arguments, if any
of the ''index'' arguments is out of range or ill-formed, or if any of
the data being manipulated cannot be converted to lists.  It will
throw an error after modifying the variable if any write trace on the
variable fails.

With the proposed ''lset'' command, the procedure to shuffle a list
becomes much more straightforward:

|  proc shuffle1b { list } {
|      set n [llength $list]
|      for { set i 0 } { $i < $n } { incr i } {
|          set j [expr {int(rand()*$n)}]
|          set temp [lindex $list $j]
|          lset list $j [lindex $list $i]
|          lset list $i $temp
|      }
|      return $list
|  }

The given implementation copies the list only once, the first time
that the line:

|          lset list $j [lindex $list $i]

is executed.  Thereafter, the list is an unshared object, and the
replacements are performed in place.

~ Reference Implementation

The author has implemented a simpler variant of the proposed command
as an object command, and also proposes to bytecode compile it,
although the implementation of bytecode compilation is incomplete.
The reference implementation also does not yet expand ''objv[[2]]''
as a list in the case where ''objc==4,'' and is known to have memory
leaks where ill-formed index arguments are presented.  It is given
here as ''concept code'' and to present its impact on performance of
some common list operations.  (Obviously, it will be completed and
reviewed with the relevant maintainers prior to being committed to the
Core.)

The core of the implementation is the following procedure:

|int
|Tcl_LsetObjCmd( clientData, interp, objc, objv )
|    ClientData clientData;      /* Not used. */
|    Tcl_Interp *interp;         /* Current interpreter. */
|    int objc;                   /* Number of arguments. */
|    Tcl_Obj *CONST objv[];      /* Argument values. */
|{
|
|    Tcl_Obj* listPtr;           /* Pointer to the list being altered. */
|    Tcl_Obj* subListPtr;        /* Pointer to a sublist of the list */
|    Tcl_Obj* finalValuePtr;     /* Value finally assigned to the variable */
|    int index;                  /* Index of the element being replaced */
|    int result;                 /* Result to return from this function */
|    int listLen;                /* Length of a list being examined */
|    Tcl_Obj** elemPtrs;         /* Pointers to the elements of a
|                                 * list being examined */
|    int i;
|
|    /* Check parameter count */
|
|    if ( objc < 4 ) {
|        Tcl_WrongNumArgs( interp, 1, objv, "listVar index ?index...? value" );
|        return TCL_ERROR;
|    }
|
|    /* Look up the list variable */
|
|    listPtr = Tcl_ObjGetVar2( interp, objv[ 1 ], (Tcl_Obj*) NULL,
|                              TCL_LEAVE_ERR_MSG );
|    if ( listPtr == NULL ) {
|        return TCL_ERROR;
|    }
|
|    /* Make sure that the list value is unshared. */
|
|    if ( Tcl_IsShared( listPtr ) ) {
|        listPtr = Tcl_DuplicateObj( listPtr );
|    }
|
|    finalValuePtr = listPtr;
|
|    /*
|     * If there are multiple 'index' args, handle each arg except the
|     * last by diving into a sublist.
|     */
|
|    for ( i = 2; ; ++i ) {
|
|        /* Take apart the list */
|
|        result = Tcl_ListObjGetElements( interp, listPtr,
|                                         &listLen, &elemPtrs );
|        if ( result != TCL_OK ) {
|            return result;
|        }
|
|        /* Derive the index of the requested sublist */
|
|        result = TclGetIntForIndex( interp, objv[i], (listLen - 1), &index );
|        if ( result != TCL_OK ) {
|            return result;
|        }
|
|        if ( ( index < 0 ) || ( index >= listLen ) ) {
|
|            Tcl_SetObjResult( interp,
|                              Tcl_NewStringObj( "list index out of range",
|                                                -1 ) );
|            return TCL_ERROR;
|        }
|
|        /* Break out of the loop if we've extracted the innermost sublist. */
|
|        if ( i >= ( objc - 2 ) ) {
|            break;
|        }
|
|        /*
|         * Extract the appropriate sublist, and make sure that it is unshared.
|         */
|
|        subListPtr = elemPtrs[ index ];
|        if ( Tcl_IsShared( subListPtr ) ) {
|            subListPtr = Tcl_DuplicateObj( subListPtr );
|            result = Tcl_ListObjSetElement( interp, listPtr, index,
|                                            subListPtr );
|            if ( result != TCL_OK ) {
|                return TCL_ERROR;
|            }
|        } else {
|            Tcl_InvalidateStringRep( listPtr );
|        }
|
|        listPtr = subListPtr;
|    }
|
|    /* Store the result in the list element */
|
|    result = Tcl_ListObjSetElement( interp, listPtr, index, objv[objc-1] );
|    if ( result != TCL_OK ) {
|        return result;
|    }
|
|    /* Finally, update the variable so that traces fire. */
|
|    listPtr = Tcl_ObjSetVar2( interp, objv[1], NULL, finalValuePtr,
|                              TCL_LEAVE_ERR_MSG );
|    if ( listPtr == NULL ) {
|        return TCL_ERROR;
|    }
|       
|    Tcl_SetObjResult( interp, listPtr );
|    return result;
|
|}

The procedure depends on a new service function,
''Tcl_ListObjSetElement'':

|int
|Tcl_ListObjSetElement( interp, listPtr, index, valuePtr )
|    Tcl_Interp* interp;         /* Tcl interpreter; used for error reporting
|                                 * if not NULL */
|    Tcl_Obj* listPtr;           /* List object in which element should be
|                                 * stored */
|    int index;                  /* Index of element to store */
|    Tcl_Obj* valuePtr;          /* Tcl object to store in the designated
|                                 * list element */
|{
|    int result;                 /* Return value from this function */
|    List* listRepPtr;           /* Internal representation of the list
|                                 * being modified */
|    Tcl_Obj** elemPtrs;         /* Pointers to elements of the list */
|    int elemCount;              /* Number of elements in the list */
|
|    /* Ensure that the listPtr parameter designates an unshared list */
|
|    if ( Tcl_IsShared( listPtr ) ) {
|        panic( "Tcl_ListObjSetElement called with shared object" );
|    }
|    if ( listPtr->typePtr != &tclListType ) {
|        result = SetListFromAny( interp, listPtr );
|        if ( result != TCL_OK ) {
|            return result;
|        }
|    }
|    listRepPtr = (List*) listPtr->internalRep.otherValuePtr;
|    elemPtrs = listRepPtr->elements;
|    elemCount = listRepPtr->elemCount;
|
|    /* Ensure that the index is in bounds */
|
|    if ( index < 0 || index >= elemCount ) {
|        if ( interp != NULL ) {
|            Tcl_SetObjResult( interp,
|                              Tcl_NewStringObj( "list index out of range",
|                                                -1 ) );
|            return TCL_ERROR;
|        }
|    }
|
|    /* Add a reference to the new list element */
|
|    Tcl_IncrRefCount( valuePtr );
|
|    /* Remove a reference from the old list element */
|
|    Tcl_DecrRefCount( elemPtrs[ index ] );
|
|    /* Stash the new object in the list */
|
|    elemPtrs[ index ] = valuePtr;
|
|    /* Invalidate and free any old string representation */
|
|    Tcl_InvalidateStringRep( listPtr );
|
|    return TCL_OK;
|    
|}

Even without bytecode compilation, the performance improvement of
array-based applications that can be achieved by the ''lset'' command
is substantial.  The following table shows run times in microseconds
(on a 550 MHz Pentium III laptop, running a modified Tcl 8.4 on
Windows NT 4.0, Service Pack #6) of the three implementations of
''shuffle'' that appear in this TIP.

|                    RUN TIMES IN MICROSECONDS
|
|                                Version
|                     shuffle1       shuffle1a       shuffle1b
|                     (Naive)      (K combinator)  (lset command)
| List length
|        1                 26               32              27            
|       10                108              152             101
|      100               1627             1462             936
|     1000             117831            14789            9574
|    10000       Test stopped           152853           96912

Similar (30-50%) improvements are observed on many of the array
related benchmarks that have been proposed.  Bytecode compilation is
expected to produce even greater improvements.

Another area where ''lset'' can achieve a major performance gain is in
memory usage.  The author of this TIP has benchmarked competing
implementations of heapsort, one using Tcl arrays, and the other using
''lset'' to manipulate lists as linear arrays.  When sorting 80000
elements, the Tcl-array-based implementation used 12.7 megabytes of
memory; the list-based implementation was faster and used only 5.6
megabytes.  The explanation is simple: each entry in the hash table
requires an allocated block of twenty bytes of memory, plus the space
required for the hash key.  The hash key is a string, and requires at
least six bytes.  When both of these objects are aligned and padded
with the overheads imposed by ''ckalloc'', they require about 80 bytes of
memory on the Windows NT platform.  The memory cost of an element of a
Tcl list, by comparison, is four bytes to hold the pointer to the
object.

~ Discussion

There are several objections that can be foreseen to this proposal.

   * ''Why implement the command in the Core and not as an extension?''

   > In a word, ''performance.''  At the present state of Tcl
     development, only Core commands can be bytecoded.  The cost of
     the hash table lookups in the ''Tcl_ObjGetVar2'' and
     ''Tcl_ObjSetVar2'' calls is significant, and can be eliminated
     from many common usages by the bytecode compiler.  Since this
     command is likely to appear in inner loops, it is important to
     squeeze every bit of possible performance out of it.

   * ''Why a new command in the global namespace?''

   > The author of this TIP feels that having a single added command
     that is parallel to the existing list commands is not polluting
     the namespace excessively.  It would be a shame if this proposal
     founders upon the Naming of Names.

   * ''Why a new command, rather than including this functionality in
     the proposed functionality of an extensible command for list
     manipulation?''

   > The author of this TIP has yet to see a formal proposal of any
     extensible list manipulation command; the closest thing appears
     to be Andreas Kupries's ''listx'' package
     (http://www.oche.de/~akupries/tcltk.html).  Given the size and
     complexity of any such modification, it is unlikely that it will
     be available in the Core in time for an 8.4 release.  The
     performance improvements achievable by the ''lset'' command are
     needed urgently.

   * ''Isn't this [29] warmed over?''

   > Several objectors to [29] indicated that they were willing to
     consider list element assignment implemented as a new command.

   * ''Doesn't this proposal depend on multiple ''index'' arguments to
     ''lindex'' ([22])?

   > This proposal can stand alone.  If multiple ''index'' arguments
     to ''lindex'' are also accepted, the resulting symmetry is
     pleasing.  Having multiple ''index'' args to ''lset'' is much
     more important, because it is horribly difficult to implement
     equivalent functionality in pure Tcl without introducing
     excessive calls to ''Tcl_DuplicateObj''.  In fact, the reference
     implementation of ''lset'' presented in this TIP was motivated by
     the fact that its author gave up on the task and resorted to C.

~ Implementation Notes

Having two versions of the syntax for the ''lset'' command is perhaps
unattractive, but neither can be left out effectively.

The syntax where the indices are packaged as a single list allows a
''cursor'' into complex list structure to be maintained in a single
variable.  The list element that the cursor designates can be altered
with a single call to the ''lset'' command, without needing to resort
to ''eval'' (a command that is both expensive and dangerous) to expand
the indices inline.

The syntax where each index is a first-class object is motivated by
the performance of array-based algorithms.  Programmers who are using
lists as arrays know exactly how many subscripts they have, and in
fact are generally iterating through them.  A typical sort of usage
might be the na�ve matrix multiplication shown below.

| # Construct a matrix with 'rows' rows and 'columns' columns
| # having an initial value of 'initCellValue' in each cell.
| 
| proc matrix { rows columns { initCellValue {} } } {
|     set oneRow {}
|     for { set i 0 } { $i < $columns } { incr i } {
|         lappend oneRow $initCellValue
|     }
|     set matrix {}
|     for { set i 0 } { $i < $rows } { incr i } {
|         lappend matrix $oneRow
|     }
|     return $matrix
| }
| 
| # Multiply two matrices
| 
| proc matmult { x y } {
| 
|     set m [llength $x];                 # Number of rows of left matrix
|     set n [llength [lindex $x 0]];      # Number of columns of left matrix
| 
|     if { $n != [llength $y] } {
|         return -code error "rank error: left operand has $n columns\
|                             while right operand has [llength $y] rows"
|     }
| 
|     set k [llength [lindex $y 0]];      # Number of columns of right matrix
| 
|     # Construct a matrix to hold the product
| 
|     set product [matrix $m $k]
| 
|     for { set i 0 } { $i < $m } { incr i } {
|         for { set j 0 } { $j < $k } { incr j } {
|             lset product $i $j 0.0
|             for { set r 0 } { $r < $n } { incr r } {
|                 set term [expr { [lindex $x $i $r] * [lindex $y $r $j] }]
|                 lset product $i $j [expr { [lindex $product $i $j] + $term }]
|             }
|         }
|     }
| 
|     return $product
| }

Note how we have an [[lset]] operation in the innermost loop, executed
(m*n*k) times.

If in this instance, we have to write:

|                 set indices [list $i $j]
|                 lset product $indices \
|                     [expr { [lindex $product $indices] + $term }]

in place of the [[lset]] shown above, we add the cost of forming the
list of indices to the cost of the inner loop.  This cost is not to be
sneezed at -- it's two expensive calls to ''ckalloc.''  (The cost can
be avoided, at some cost in readability, by maintaning a variable
containing the index list, and altering its elements with other uses
of [[lset]].)

Richard Suchenwirth suggested the compromise that appears in this
proposal.  This scheme will perilous to performance if implemented
naively.  If the implementation of [[lset]] simply calls
''Tcl_ListObjGetElements'', look what happens to the inner loop of our
''shuffle1b'' procedure:

|      for { set i 0 } { $i < $n } { incr i } {
|          set j [expr {int(rand()*$n)}]
|          set temp [lindex $list $j]
|          lset list $j [lindex $list $i]
|          lset list $i $temp
|      }

   * Initially, {set i 0} sets i to the constant "0"; it is a string.

   * Evaluating the conditional {$i < $n} will shimmer i to an integer;
     now it's an integer.  (We had to do a call to strtol here.)

   * The [[lindex $list $i]] call now has to consider $i as a list of
     indices, and shimmers it to the list.  This discards the internal
     rep, parses the string rep into a list, and then reconverts its
     first element to an integer.

   * OK, now the 'lset' is happy, and no further shimmering occurs...

   * ... until we get to the {incr i}.  Now we go back to the string rep
     once again, shimmer it to an integer (yet another call to strtol),
     and invalidate the string rep because we've incremented the integer.

   * Now we get back into the [[lindex]] once again, and need a list
     rep.  This time, we have to format the integer as a string, parse
     it as a list, take the object representing element 0, and reparse
     that as an integer.

This sequence has converted the integer to and from a string, and
performed four calls to ''ckalloc'', but resulted in the same integer
that we started with!

It is possible for a sufficiently smart compromise implementation
to avoid all this shimmering.  In the case where ''objc==4'', the
''lset'' command must:

 1. Test whether ''objv[[2]]'' designates an object whose internal
    representation holds an integer.  If so, simply use it as an index.

 2. Test whether ''objv[[2]]'' designates an object whose internal
    representation holds a list.  If so, perform the recursive
    extraction of indexed elements from sublists described above.

 3. Form the string representation of ''objv[[2]]'' and test whether
    it is ''end'' or ''end-'' followed by an integer.  If so, use it
    as an index.

 4. Attempt to coerce ''objv[[2]]'' to an integer; if successful, use
    the result as an integer.

 5. Attempt to coerce ''objv[[2]]'' to a list; if successful, use
    the result as an index list.

 6. Report a malformed ''index'' argument; the ''indexList'' parameter
    is not a well-formed list.

This logic handles all the cases of singleton lists transparently; it
is effectively a simple-minded type inference that optimizes away
needless conversions.  With it in place, none of the ''lset'' examples
shown in this TIP will suffer from type shimmering.

In the event that the related [22] is approved, the logic for parsing
an index list will likely be combined with that used in the ''lindex''
command.

Bytecoding variadic commands like ''lset'' presents some interesting
technical challenges; a discussion in progress on the Tcl'ers Wiki
(http://purl.org/thecliff/tcl/wiki/1604) is recording the design
decisions being made for bytecoding ''lset'' so that they can be
applied to similar commands in the future.

~ See Also

[22], [29].

~ Change History

This TIP has undergone several revisions by the original author.
The most significant was made on 20 May 2001, where the syntax was
revised to allow for either several indices inline on the command line
or a list of indices.

~ Copyright

This document has been placed in the public domain.
Deleted tip/34.tip.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76












































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TIP:            34
Title:          TEA 2.0
Version:        $Revision: 1.3 $
Author:         Mo DeJong <[email protected]>
Author:         Andreas Kupries <[email protected]>
State:          Draft
Type:           Project
Vote:           Pending
Created:        03-May-2001
Post-History:   
Tcl-Version:    8.4

~ Abstract

The original TEA specification, documentation, and implementation have
fallen out of date.  Numerous complaints about the difficulty of
creating a TEA compliant package have appeared on news:comp.lang.tcl
The existing build system works but it is a pain to maintain mostly
because there are two build systems, one for unix and another for
windows.  This document describes how some of these concerns can be
addressed.

~ Rationale

As new software is released, existing documentation becomes obsolete.
Some of the existing TEA documentation is now so badly out of date
that suggested software releases are no longer available.  The
solution to this problem is simple, the TEA documentation and
implementation must be updated.

The build system itself is in need of an update.  The Unix and Windows
versions of the build system are not synchronized.  There are a number
of features that are simply not implemented in the Windows version.
The most straightforward way of dealing with this problem is to merge
the two build systems.  Some popular extensions have already taken
this approach, Itcl for example uses a single ''configure.in'' script
to build the Unix and Windows versions.  While switching to a single
''configure.in'' is a big step, it will significantly simplify
maintenance and make life a lot easier in the long run.

Tcl's build system does not depend on ''config.guess'' and
''config.sub'' to determine build and host triples.  Instead, it
depends on the output of ''uname -s'' and ''uname -r''.  That works
for native builds but makes it very painful to cross compile.  For
example, a user might want to build Windows binaries under Linux.
Tcl's existing build system makes this much harder than it needs to
be.  Upgrading to ''autoconf 2.50'' is the best way to address this
problem.

Tcl's build system passes a large number of ''-D'' flags to the
compiler instead of making use of a ''config.h'' file.  Personal
experience has shown that using a ''config.h'' file is a superior way
of dealing with configure time defines.

~ Implementation Notes

Implementing this TIP is by no means an easy task.  Build system
changes are by far the most dangerous since a mistake that breaks
something on some infrequently used configuration will not be noticed
until some time in the future.  One can only ask for forgiveness up
front since it is a virtual certainty that these sorts of changes are
going to break something.  The needed documentation changes are
straightforward, but the actual process make take a long time.

~ Alternatives

The alternative is to continue to use the existing system.  Things
would get no worse but they would also get no better.

~ Comments

Andreas Kupries: Is it possible to use 'tclConfig.h' instead of 'config.h' ? IMHO this file should be installed along with the other headers and the current name is much to generic then.

~ Copyright

This document has been placed in the public domain.
Deleted tip/35.tip.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
















































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TIP:            35
Title:          Enhanced Support for Serial Communications
Version:        $Revision: 1.11 $
Author:         Rolf Schroedter <[email protected]>
Author:         Rolf Schroedter <[email protected]>
State:          Accepted
Type:           Project
Vote:           Done
Created:        06-Jun-2001
Post-History:   
Tcl-Version:    8.4

~ Abstract

Tcl's support for RS-232 is very rudimentary.  Mainly it allows to
setup the communication rate [[fconfigure -mode]] and to read and
write data with the standard Tcl functions.  Real serial
communications are often more complex.  Therefore it is proposed to
add support for hardware and software flow control, polling RS-232
(modem) status lines, and watching the input and output queue.  This
is all to be implemented via additional [[fconfigure]] options.

~ Rationale

There is an undamped interest in serial communications, because it's
very easy to connect external hardware to a computer using the RS-232
ports.

However Tcl's support for serial communications is not complete.  Real
applications often need more than setting the baud rate and to
read/write data bytes.

Especially if the external hardware is slow or the communication rate
is high one needs support for flow-control (hard- and software).
These features are provided by the operating system drivers, but Tcl's
[[fconfigure]] doesn't support it.

On the the other hand there are cases that the external hardware makes
static use of the RS-232 signals to signal external events via the
modem status lines or even to be powered by the RS-232 control lines.

Additionally for non-blocking serial I/O it may be interesting for the
Tcl application to know about the status of the input and output
queues to read a fixed size block or to support communication
timeouts.

At this opportunity it is proposed to move the documentation of the
serial port fconfigure options form the ''open.n'' man-page to
''fconfigure.n''.

~ Specification

It is proposed to have following set of [[fconfigure]] options for
serial communications:

 -mode baud,parity,data,stop: ''(Windows and Unix)''.  Already
    implemented.

 -handshake mode: ''(Windows and Unix)''.  This option is used to
    setup automatic handshake control.  Note that not all handshake
    modes maybe supported by your operating system.  The mode
    parameter is case-independent.

  > If mode is ''none'' then any handshake is switched off.
    ''rtscts'' activates hardware handshake.  For software handshake
    ''xonxoff'' the handshake characters can be redefined with
    [[fconfigure -xchar]].  An additional hardware handshake
    ''dtrdsr'' is available only for Windows.  There is no default
    handshake configuration, the initial value depends on your
    operating system settings.  The -handshake option cannot be
    queried, because the operating system settings may be ambiguous.

 -xchar {xonChar xoffChar}: ''(Windows and Unix)''.  This option is
    used to change the software handshake characters.  Normally the
    operating system default should be DC1 (0x11 hex) and DC3 (0x13
    hex) representing the ASCII standard XON and XOFF characters.  
    When queried -xchar returns a list of two characters representing 
    the XON and XOFF characters respectively.

 -timeout msec: ''(Windows and Unix''. This option is used to set 
    the timeout for blocking read operations. It specifies the 
    maximum interval between the receiption of two bytes in
    milliseconds. For Unix systems the granularity is 100 milliseconds.
    The -timeout option does not affect write operations or
    nonblocking reads. This option cannot be queried.

 -ttycontrol {signal boolean signal boolean ...}: ''(Windows and
    Unix)''.  This option is used to setup the handshake output lines
    permanently or to send a BREAK over the serial line.  The
    ''signal'' names are case-independent.

  > {RTS 1 DTR 0} sets the RTS output to high and the DTR output to
    low.  For POSIX systems {BREAK 1} sends a break signal
    (zero-valued bits) for 0.25 to 0.5 seconds and {BREAK 0} does
    nothing.  For Windows the break is enabled and disabled with
    {BREAK 1} and {BREAK 0} respectively.  It's not a good idea to
    change the RTS (or DTR) signal with active hardware handshake
    ''rtscts'' (or ''dtrdsr'').  The result is unpredictable.  The
    -ttycontrol option cannot be queried.

 -ttystatus: ''(Windows and Unix)''.  The -ttystatus option can only
    be queried.  It returns the current modem status and handshake
    input signals.  The result is a list of signal,value pairs with a
    fixed order, e.g. {CTS 1 DSR 0 RING 1 DCD 0}.  The ''signal''
    names are returned upper case.

 -queue: ''(Windows and Unix)''.  The -queue option can only be
    queried.  It returns a list of two integers representing the
    current number of bytes in the input and output queue respectively.

 -sysbuffer inSize: 

 -sysbuffer {inSize outSize}: ''(Windows only, Unix ?)''.  This option
    is used to change the size of Windows system buffers for a serial
    channel.  Especially at higher communication rates the default
    input buffer size of 4096 bytes can overrun for latent systems.
    The first form specifies the input buffer size, in the second form
    both input and output buffers are defined.

 -pollinterval msec: ''(Windows only)''.  Already implemented.

 -lasterror: ''(Windows only, Unix?)''.  Already implemented for
    Windows.

~ Implementation Details

For Unix (''termios.h'') systems the proposed changes are very
straight forward, because Unix channels can be configured blocking or
non-blocking.  One only needs to add the serial [[fconfigure]] options
calling the appropriate ''ioctl()'' functions to configure the serial
port.

For Windows reading and writing files is generally blocking.
Especially with activated handshake the serial communication can stop
forever.  Therefore the Windows implementation needs at least a
writing thread preventing Tcl's main application to block.
Additionally Windows provides a reach set of special APIs for serial
communication which needs to be translated to [[fconfigure]] options.

There is one special point about Windows: For making multiple threads
accessing a serial port, it needs to be opened with the OVERLAPPED
flag set.  Tcl detects a serial port only after opening it without the
OVERLAPPED flag.  Therefore this port has to be reopened, which
requires a little change to ''tclWinChan.c'' and ''tclWinPort.h''.

Macintosh systems - ?

~ Changed Files

 tclUnixChan.c: Add [[fconfigure]] options.

 tclWinPort.h: Declare a new function ''TclWinSerialReopen()''

 tclWinChan.h: Call ''TclWinSerialReopen()'' after detecting the
   serial port.

 tclWinSerial.c: Partial rewrite of Tcl's serial driver.  The current
    implementation only performs blocking output.  Add [[fconfigure]]
    options.

 fconfigure.n: Serial [[fconfigure]] options should be documented
    here.

 open.n: Serial port filenames are documented here.  Add a link to
    [[fconfigure]] for additional serial options.

~ Timeouts

It has also been proposed to add a [[fconfigure -timeout]] option
specifying read and write timeouts.  Together with a blocking read a
timeout could be used to wait for an expected number of data bytes
from the serial port.  There are two arguments against timeouts:

 1. Adding timeout to blocking I/O at the driver level radically
    changes the behaviour of write operations.  This adds a lot
    of oddity to serial communications.

 2. Timeouts can easily be implemented at Tcl level using non-blocking
    I/O together with Tcl's event loop.  Additional support is given
    by [[fconfigure -queue]].

July 03, 2001:
On the other hand timeout for read operations can easily be 
implemented in a cross-platform way by using the VMIN/VTIME settings
for Unix and the COMTIMEOUTS for Windows.
That's why the author finally agrees with the -timeout proposal.

~ Restore settings at close ?

It has also been proposed that Tcl should not restore the original
serial ports settings at [[close $chan]]. IMO it doesn't hurt, 
because anyway an application should care about setting up the serial
port properly before using. Without restoring a Tcl script could be 
used as a ''poor'' stty, considering however that Tcl 
does not provide a complete control over serial settings.

So the proposal is to remove the current save/restore mechanism
from the Unix implementation for serial ports.

~ Source code patches

The patches have been uploaded to the sourceforge patch tracker:
    ID=438509 TIP#35 Patches: Serial Port Enhancements
    file=tip35patch.tgz

~ Copyright

This document has been placed in the public domain.
Deleted tip/36.tip.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92




























































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TIP:		36
Title:		Library Access to 'Subst' Functionality
Version:	$Revision: 1.4 $
Author:		Donal K. Fellows <[email protected]>
State:		Final
Type:		Project
Tcl-Version:	8.4
Vote:		Done
Created:	13-Jun-2001
Post-History:	

~ Abstract

Some applications make very heavy use of the ''subst'' command - it
seems particularly popular in the active-content-generation field -
and for them it is important to optimise this as much as possible.
This TIP adds a direct interface to these capabilities to the Tcl
library, allowing programmers to avoid the modest overheads of even
''Tcl_EvalObjv'' and the option parser for the ''subst'' command
implementation.

~ Functionality Changes

There will be one script-visible functionality change from the current
implementation; if the evaluation of any command substitution returns
TCL_BREAK, then the result of the ''subst'' command will be the string
up to that point and no further.  This contrasts with the current
behaviour where TCL_BREAK (like TCL_CONTINUE) just causes the current
command substitution to finish early.

~ Design Decisions

The code should be created by effectively splitting
''Tcl_SubstObjCmd'' in the current ''.../generic/tclCmdMZ.c'' into two
pieces.  One of these pieces will have the same interface as the
present code and will contain the argument parser.  The other piece
will be the implementation of the ''subst'' behaviour and will be
separately exposed at the C level as well as being called by the
front-end code.

The code should take positive flags stating what kinds of
substitutions should be performed, as this is closest to the current
internal implementation of the ''subst'' command.  These flags will be
named with the prefix TCL_SUBST_*.  For programming convenience, the
flag TCL_SUBST_ALL will also be provided allowing the common case of
wanting all substitutions to be performed with a minimum of fuss.

The string to be substituted will be passed in as a ''Tcl_Obj *'' too,
as this is both easiest to do from the point-of-view of the front-end
code and permits additional optimisation of the core at some future
point if it proves necessary and/or desirable.  By contrast, passing
in a standard C string or a ''Tcl_DString *'' does not permit any such
optimisations in the future.

The code should return a newly-allocated ''Tcl_Obj *'' as this allows
for the efficient implementation of the front-end involving no
re-copying of the resulting string.  It also allows error conditions
to be represented by NULL (with an error message in the interpreter
result) and does not force a Tcl_DString reference to be passed in as
an ''out'' parameter; returning the result gives a much clearer call
semantics.  Another advantage of using ''Tcl_Obj''s to build the
result is the fact that they have a more sophisticated memory
allocation algorithm that copes more efficiently with very large
strings; when large and small strings are being combined together (as
is easily the case in ''subst'') this can make a substantial
difference.

~ Public Interface

''Added to .../generic/tcl.h''

|#define TCL_SUBST_COMMANDS    0x01
|#define TCL_SUBST_VARIABLES   0x02
|#define TCL_SUBST_BACKSLASHES 0x04
|#define TCL_SUBST_ALL         0x07

''Added to .../generic/tcl.decls''

|declare someNumber generic {
|    Tcl_Obj * Tcl_SubstObj( Tcl_Interp *interp,
|                            Tcl_Obj *objPtr,
|                            int flags)
|}

~ Implementation

The implementation is to be developed upon acceptance of this TIP, but
will involve ''Tcl_AppendToObj'' and ''Tcl_AppendObjToObj''.

~ Copyright

This document has been placed in the public domain.
Deleted tip/37.tip.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149





















































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TIP:            37
Title:          Uniform Rows and Columns in Grid
Version:        $Revision: 1.9 $
Author:         Peter Spjuth <[email protected]>
Author:         Kevin Kenny <[email protected]>
State:          Accepted
Type:           Project
Vote:           Done
Created:        19-Jun-2001
Post-History:   
Tcl-Version:    8.4

~ Abstract

This TIP proposes to add a ''-uniform'' option to ''grid
rowconfigure'' and ''grid columnconfigure'' so as to make it easier to
create layouts where cells are constrained to have identical
dimensions.

~ Introduction

The geometry managers in Tk are very powerful and can do most things
needed to layout a GUI.  One thing that is tricky to do though is to
put widgets in rows or columns of the same width.  This would be
useful for example to layout a row of buttons symmetrically.  This
could easily be done with the grid manager if an additional option is
added.

~ Specification

Anywhere ''column'' is used below, the same applies to ''row'' too.

A new option, ''-uniform'', is added to ''grid columnconfigure''.  The
option takes an arbitrary string, the default value being the empty
string.  Any column with a non-empty value will be grouped with other
columns with the same value.  Each column in a group will get the size
k*''-weight'' (in this aspect a ''-weight'' value of 0 is used as 1)
, where k is set so that no column becomes smaller.  E.g., if all columns
in a group have the same ''-weight'' they will all get the size of the
largest member.

In the grid algorithm ''-uniform'' and ''-weight'' will be used as
specified above in the calculation of the requested size (the first step in
the description of the grid algorithm in grid(n)), but for the distribution
of extra size (second step) only ''-weight'' will be considered.  This
means that the second step is not altered at all by this.

~ Rationale

Getting symmetry in a layout today is possible but even for a simple
case it gets tricky if you want more than a half decent result.  Message
catalogs changing strings and options databases changing appearances
can make a GUI very dynamic and normally you never need to count pixels
since geometry managers do that for you.  For symmetry though you suddenly
have to handle pixel details yourself, details that are handled so much
better by a geometry manager.  With a ''-uniform'' option, grid can do
symmetry for you in a simple way that takes care of all the details.

To only consider ''-weight'' in the extra size distribution is mainly
a matter of simplicity.  It gives a simpler algorithm that is both
easier to explain to the user and to code.

To uphold the uniform property it would be needed to force any zero
''-weight'' value in a group where any non-zero ''-weight'' exists to
be set to one before doing the resize calculations.  A bit complicated
and the only benefit for the user would be to only have to specify
''-weight'' for one column in a group. But in practice this is hardly
no gain at all since a typical usage looks like this:

|grid columnconfigure . {0 1 2} -uniform a -weight 1

I'm not sure if someone would have a use for the effect you would get
by mixing zero and non-zero weights in a group but this leaves you
the freedom to do so.

~ Examples

To clarify how -uniform affects a grid here are some examples.

|button .b1 -text a
|button .b2 -text b
|button .b3 -text example
|button .b4 -text xyzzy
|grid .b1 .b2 .b3 .b4 -sticky news
|grid columnconfigure . {0 1 2 3} -uniform a -weight 1

Initially all columns will be equal and if resized, all columns will
change equally.

|Initial: |[   a   ]|[   b   ]|[example]|[ xyzzy ]|
|Shrunk:  |[  a  ]|[  b  ]|[xampl]|[xyzzy]|

Another example. Instead we do:

|grid columnconfigure . {0 2} -uniform a -weight 1
|grid columnconfigure . {2}   -weight 2
|grid columnconfigure . {1 3} -uniform b -weight 0
|grid columnconfigure . {1}   -weight 1

Initially column 0 will be half the size of column 2, columns 1
and 3 will be equal.
Resizing will affect colums 0 and 1 half of how column 2 is
affected. Column 3 is static.

|Initial:  |[ a ]|[  b  ]|[example]|[xyzzy]|
|Shrunk:   |[a]|[ b ]|[amp]|[xyzzy]|
|Expanded: |[  a  ]|[   b   ]|[  example  ]|[xyzzy]|

~ Implementation

A quick try shows that this is fairly straightforward to implement.
If the option is not used the memory cost is a ''Tk_Uid'' field (or
similar if some other mechanism than ''Tk_Uid'' is used) in the column
slot structure to hold the option, and the CPU overhead is small.

~ Summary of Objections

 * Kevin Kenny raised the issue that the proposed implementation
   uses a Tk_Uid for the "uniform" key, leading to potential resource
   leaks.  Subsequent discussion has convinced him that the potential
   for trouble is small; in any case, it need not block approval.
   The ensuing discussion veered off into a long thread about
   reclaiming the memory used for Tcl_Obj structures; the thread
   is not pertinent to this TIP.

 * George Howlett questioned the need for this feature, citing the
   lack of compelling examples.  The original author replied with
   the example of a dialog holding multiple buttons containing
   text of different widths, and showed how the Tcl code to manage
   such a dialog is clumsy.

 * George Howlett raised the issue of a detailed specification of
   the behavior of -uniform when insufficient space is available to
   satisfy the request.  The original author added clarification in
   the "Examples" section, and supplied additional examples in
   discussions on the mailing list, notably
   http://www.geocrawler.com/archives/3/7375/2001/7/50/6211900/

 * George Howlett also asserted that the desired semantics can
   be achieved with Tcl code that either lays out a fixed
   configuration of the widget (with, for example, the ''-minsize''
   option of ''grid columnconfigure'') or responds to the
   ''<Configure>'' event.  Probably the best summary of the ensuing
   discussion is that we need to strike a balance between
   richness of the API and simplicity of the implementation.

~ Copyright

This document has been placed in the public domain.
Deleted tip/38.tip.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134






































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TIP:		38
Title:          Add Support for Default Bindtags
Version:	$Revision: 1.2 $
Author:         Bryan Oakley <[email protected]>
State:		Draft
Type:           Project
Vote:		Pending
Created:	27-Jun-2001
Tcl-Version:    8.4
Post-History:	

~ Abstract

This TIP proposes to add support for the ability to change the default
list of bindtags for a class of widgets.

~ Introduction

Bindtags are an extremely useful addition to the Tk toolkit.  By
modifying the bindtags for a given widget, enhanced bindings can be
added, or default behaviors removed, without modifying actual
bindings.

At present, the default bindtags for a widget are fixed.  All widgets
are created with the same default bindtags.  If an application
programmer wants to alter the bindtags for a widget, she must do so on
a case by case basis.

By allowing the programmer to define their own default bindtags, one
can leverage the power of bindtags with fewer lines of code.  In
addition, changing the default bindtags can not only affect all
widgets in a block of code, but widgets that are created at runtime,
even if created by imported packages that are beyond the programmer's
control.

~ Specification

An enhancement to the bindtags command is suggested.  At present, the
only valid use of bindtags is to include a widget name as the first
argument.  Therefore, adding a new parameter that does not begin with
a dot will not break any existing scripts (that is to say, any script
that presently has the command ''bindtags default'' is broken).

This TIP proposes the following enhancement to the bindtags syntax:

| bindtags default class tagList

''default'' is the literal name of a subcommand

''class'' is a widget class (e.g. Listbox, Text, etc) or ''*'' to
signify all classes.  A default for a specific class will override the
default for all.

''tagList'' is a Tcl list of bindtags, with support for the following
meta-characters, ala bind:

 %C: the widget class

 %W: the widget path for a specific instance of a widget

 %%: replaced with a single %

For example:

| bindtags default Text [list Special %W %C . all]
| => Special %W %C . all
| text .t
| => .t
| bindtags .t
| => Special .t Text . all

If ''tagList'' is null (e.g. ''bindtags default Text {}''), the
default bindtag reverts to the existing behavior.  Because of this it
is not possible to associate a null bindtag list to a widget, but it's
doubtful that would ever be an issue.  One could just as easily
associate a bogus bindtag that has no bindings to get the same result.
(As an alternate suggestion, we could allow null bindtag lists, and
use ''bindtags default Text'' without a tagList to specify that the
core defaults be used).

When a widget is created, its default bindtags will be those specified
by the programmer via the enhanced syntax.  If no defaults have been
specified, the current behavior will be used.  For widgets that take a
-class parameter (e.g. frames), it will choose the bindtags based on
its requested class rather than its base class.  For example, ''frame
.foo -class Combobox'' will use the bindtags for the class
''Combobox'' rather than the class ''Frame''.

~ Rationale

Occasionally it is desirable to add a special bindtag to the front or
end of the bindtag list for all widgets in an application.  Or, one
way want to replace the widget class bindtag with their own or remove
it altogether.  Without a way to specify a default, a programmer must
issue a bindtag command for every widget after it is created.  This
has an impact on overall performance.  In addition, it can be a source
of errors over time; if a new programmer begins work on a project, she
may not realize that widgets need this new bindtag and fail to add it
in her code.

In addition, when widgets are created dynamically during the course of
a user's interaction with the system (for example, when a dialog is
created before it is popped up), the bindtags must be added at
runtime.  Often this is impractical if the dialog or widget(s) belong
to an imported package that the programmer can't modify.

~ Alternatives to this TIP

An alternative way to implement this TIP might be to modify each
widget command such that it becomes configurable.  An example might
be:

| button configure -bindtags {Special %W %C . all}
| => Special %W %C . all
| button .foo
| => .foo
| bindtags .foo
| Special .foo Button . all

Given that the widget commands now have no notion of class-level
configuration values, it seems awkward to introduce it at this time.
It would, however, open up the door for adding other features in
future versions of Tk.  I can envision, for example, ''button
configure -renderer myButtonRenderProc'', which would call
myButtonRenderProc to render button widgets instead of using the
default C-based renderer.  This might make it possible to support a
pluggable look and feel some day.

Keeping all of the bindtags interaction with the bindtags command
seems like a better way to go.

~ Copyright

This document has been placed in the public domain with great vigor.
Deleted tip/39.tip.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90


























































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TIP:            39
Title:          Add New Standard Tk Option: -component
Version:        $Revision: 1.2 $
Author:         Bryan Oakley <[email protected]>
State:          Draft
Type:           Project
Vote:           Pending
Created:        04-Jul-2001
Post-History:   
Keywords:       compound,megawidget
Tcl-Version:    8.4

~ Abstract

This TIP proposes to add a new standard option, ''-component'', for
all Tk widgets.

~ Introduction

One of the problems with creating compound widgets (or "megawidgets")
in Tk is library code that doesn't know whether a widget is a widget
or whether it is merely a component of a larger compound widget.

This TIP suggests a new common option for all widgets that defines
whether a widget is merely a component of a larger compound object.
The value of this option would normally be the empty string, but could
be set to the name of a widget that is the "root" of a compound widget
(typically a component window's parent).

For example, consider a prototypical labelled entry widget that is
made up of a frame (.f), and entry widget (.f.e) and a label (.f.l).
These might be defined as follows:

| frame .f -class LabelledEntry 
| entry .f.e -component .f
| label .f.l -component .f

Internal commands that act upon widgets could use this information to
alter their behavior for component widgets.  For example,
''tk_focusNext'' and ''tk_focusPrev'' could ignore components when
figuring out where to send focus, typically as a result of the user
pressing <Tab> or <Shift-Tab>.  This would help sole a nagging problem
with many compound widgets.

We might want to modify [[winfo children]] to ignore component windows
as well (unless, for example, ''-showcomponents'' is set to true),
only reporting those children added by external entities.  For
example, consider a compound widget that implements a scrollable
container.  This widget might be built with a frame (.f), a vertical
scrollbar (.f.v) and a horizontal scrollbar (.f.h).  After a user adds
their own widgets to this window they would expect [[winfo children
.f]] to return only the windows they created, and might be confused
(or at least annoyed) by the presence of these internal windows.

~ Specification

Suggested wording for the ''options'' man page:

| Command-Line Name: -component
| Database Name: component
| Database Class: Component

 > ''Designates that this widget is a component of a larger widget.
   This option is normally the empty string.  If it is not the empty
   string, it should be set to the "root" of the compound widget.  For
   example, if a compound widget is made up of frame ".f" and an entry
   widget ".f.e", the latter will have as it's component value ".f"
   designating that it is a component of the compound widget rooted at
   ".f"''

In addition, ''tk_focusPrev'' and ''tk_focusNext'' should take the
value of this flag into consideration when determining where focus
should next be given (i.e. it should not give focus to components;
focus should be given to root widgets, which shall be responsible for
redirecting focus as required).

Once this TIP gets implemented, subsequent TIPs can be produced to
define how additional Tk library functions and commands can be
modified to take advantage of this new information.

~ Rationale

We need a standardized way of determining whether a widget is an
atomic object or part of a larger compound object.  This has several
uses, the most obvious (to me, anyway) being focus management.

~ Copyright

This document has been placed in the public domain with unabashed hope 
for a brighter future.
Changes to tip/4.tip.
1
2
3

4
5
6
7
8
9

10
11
12

13
14
15
16
17
18
19
1
2

3
4
5


6

7
8
9

10
11
12
13
14
15
16
17


-
+


-
-

-
+


-
+







TIP:            4
Title:          Tcl Release and Distribution Philosophy
Version:        $Revision: 1.10 $
Version:        $Revision: 1.4 $
Author:         Brent Welch <[email protected]>
Author:         Donal K. Fellows <[email protected]>
Author:         Larry W. Virden <[email protected]>
Author:         Larry W. Virden <[email protected]>
State:          Draft
Type:           Informative
Type:           Informational
Vote:           Pending
Created:        26-Oct-2000
Post-History:   
Post-History:
Discussions-To: news:comp.lang.tcl

~ Abstract

This document outlines how Tcl should be distributed, with
particular reference to issues related to building a
distribution with the ''batteries included'' so that most people
103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
118
119
101
102
103
104
105
106
107

108


109
110
111
112
113
114
115







-
+
-
-








 1. The registry and dde extensions for the Windows platform.

 1. The [[incr Tcl]] extension.  

 1. The TclX extension.  There are some historical features of
    TclX that should not necessarily be included, including the
    tclx shell and its alternate library format.  However, the
    tclx shell and its alternate library format.
    TclX help system should not only be included, but updated to
    include info on all commands included in the distribution.

 1. The Expect extension for UNIX platforms.

 1. The TkCon enhanced console application.

~ Optional Packages

130
131
132
133
134
135
136
137

138
139

140
141
142
143
144
145
146
147
148
149
150
151
152
153

154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
126
127
128
129
130
131
132

133
134

135
136
137
138
139
140
141
142
143
144
145
146
147
148

149
150
151
152


153
154
155
156
157
158









159
160
161
162
163
164
165







-
+

-
+













-
+



-
-






-
-
-
-
-
-
-
-
-








 > 1. command line processing

 > 1. FTP client library

 > 1. FTP server

 > 1. HTML and JavaScript generation
 > 1. HTML generation

 > 1. Math and statistics utilities
 > 1. Math utilities

 > 1. MIME encoder and parser

 > 1. CGI processing (ncgi)

 > 1. NNTP client

 > 1. POP3 client

 > 1. Profiler for Tcl scripts

 > 1. Event counters and interval timers

 > 1. Structures, including tree, stack, graph, queue
 > 1. Sturctures: including tree, stack, graph, queue

 > 1. URI parsing

 > 1. Text string manipulation utilities (trim, tab, etc.)

 1. BLT.

 1. [[incr Tk]] and [[incr Widgets]].

 1. TkTable.

 1. The Standard Tk Library of Tcl/Tk scripts.  Currently
    this includes packages for:

 > 1. BWidgets

 > 1. mclistbox

 1. Img

~ Rationale

The small "core" distribution must retain its identity for those
applications that embed the Tcl interpreter into constrained
environments and require a small footprint. The footprint must
remain small, and in fact it should grow smaller, if possible.
For example, in the early days of Tcl it was possible at compile
Deleted tip/40.tip.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282


























































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TIP:            40
Title:          Documentation Generator for Tcl Scripts
Version:        $Revision: 1.2 $
Author:         Arjen Markus <[email protected]>
State:          Draft
Type:           Project
Vote:           Pending
Created:        04-Jul-2001
Post-History:   
Keywords:       documentation,automatic generation,HTML,reference
Tcl-Version:    8.0

~ Abstract

This TIP proposes the adoption of a standard documentation format for
Tcl scripts and the implementation of a simple tool that will extract
this documentation from the source code so that it may be turned into
a programmer's guide.  This is in essence akin to documentation tools
like the well-known ''javadoc'' utility for Java programs and Eiffel's
short utility.

~ Introduction

The style guide by Ray Johnson presents a documentation standard that is
easy to use and is in fact adopted in the Tcl/Tk distribution.
Other than this, the standard has not been enforced or encouraged. It is
also not backed up by some tool (as far as I know) that can generate
pretty looking documents from this.  As a consequence, styles of
documentation may vary widely and at times it is necessary to read the
source code (looking for descriptions) to understand how to use the
script.

The availability of such a tool may encourage people to use the standard,
as the costs of generating the documentation are relatively low.
The tool must accommodate for variations and therefore be flexible -
for instance by providing customisable procedures to support the user's
preferred header format.

The tool also needs to distinguish the types of output: in many cases HTML
output is desirable to make it look pretty and provide hypertext facilities,
in other cases it should provide plain text, formatted so that it can be
read in any ordinary text editor or printed quickly.

Parallel to the development of such a tool, a standard or checklist should be
assembled of what information programmer ought to provide, the version of
Tcl/Tk, extensions that need to be present, what functionality is offered
and so on.

~ Rationale

Automatic documentation generation has two goals: improving usability and
improving maintainability. The first means: pleasant looking documentation,
at low cost for the author, is easy to use. One can also avoid reading the
source code. Further, it ensures homegeneously looking documentation.

Improving the maintainability is achieved by having more or less
technical documentation near the code. There is no need for separate
documents, something which enhances the risk of discrepancies. Remember
the DRY principle: Don't Repeat Yourself.

~ What information

A user clearly needs different information than a maintainer. For the
user it is important to know what functionality is provided, what other
packages or extensions are needed, which (public) procedures are available
and how to use them.

For the maintainer: having an overview of the source files helps finding
the procedures. Part of this information can be extracted directly from
the source (such as via inspection of the proc, package and
namespace statements).

~ Formats

Use the format proposed by the style guide as a guideline (certainly
for the reference implementation):

| # pkg_compareExtension --
| #
| #  Used internally by pkg_mkIndex to compare the extension of a file to
| #  a given extension. On Windows, it uses a case-insensitive comparison
| #  because the file system can be file insensitive.
| #
| # Arguments:
| #  fileName     name of a file whose extension is compared
| #  ext          (optional) The extension to compare against; you must
| #               provide the starting dot.
| #               Defaults to [info sharedlibextension]
| #
| # Results:
| #  Returns 1 if the extension matches, 0 otherwise

(This comes from the "package.tcl" script file that came with Tcl 8.3.1,
it is consistent with the Tcl style guide by Ray Johnson)

~ Requirements

The requirements are simple to describe:

* Implementation shall be in Tcl, to guarantee availability and
  portability.

* The system shall be easy to extend to new documentation formats
  (Implementation note:  small procedures that register the
  information piece by piece)

* It shall be easy to extend to new output formats
  (Implementation note: small procedures that format the registered information)

* It shall properly deal with organisational aspects:  source file,
  package, namespace.

~ Summary of reactions

The replies on the first version of this TIP were quite positive: both
Donal Porter and Cameron Laird think it is a good idea. Juan Gil gave
a very extensive reaction, describing a more general framework that
would eventually result in a system for generating all kinds of output
from Tcl scripts, TIPs and so on.

To do him more justice, without repeating the entire document, he
proposes the use of XML as an intermediate format holding the structure
of the information. The advantage is the possibility to reuse all
existing tools and (de facto) standards, notably DocBook, in this
context.

Even though I share some of the enthousiasm of Juan, I am a bit awed
by it: the original idea of this TIP is not so much creating a
publication system, but rather an easy-to-use tool for
automatically extracting useful information in a nice shape.
Eventually it could develop into something of the kind Juan describes,
but that should not be the first goal.

The technique for representing the information structure he proposes, is
quite useable (and akin to the rendering process of TIPs):

* Parse the script and store the pieces in "qualified lists".

* Such qualified lists are an intermediate format, either in memory or
  stored in a suitable format on disk.

* These lists and lists of lists are then passed to the output
  renderers.

The first problem to solve is then finding a suitable structure for the
information we need to extract. This is the subject of the next section.

Will Duquette and Andreas Kupries mentioned the frequent use of
specialised commands that introduce new commands (rather than a
straightforward call to "proc"). This feature will have to be looked into,
because if you only look for lines like "proc some-command { ... } {",
you might well miss the essentials of such applications.

~ Information in a Tcl script

Tcl scripts are organised in three essentially unrelated ways:

* Individual files contain the code

* Programs consist of one or several files of code

* Packages are used to identify code that belongs together

In practice these methods will be used in accord with each other, but
there is no guarantee for instance, that a source file contains only one
package and programs will probably quite often use more than one
package.

On a smaller scale, the following items are of importance:

* Procedures or commands defined inside some namespace (exported or not)

* Variables local to the enclosing namespace or global to the
  application

For a user it will be important to know what a program or package has to
offer and how to get this functionality:

* A description of the program (with its command-line arguments,
  if any, the packages it uses, if they come separately)

* A description of the package or packages (assuming it is properly
  installed, its name and version should be enough to load the
  scripts and binaries)

* A description of each public procedure and a description of the
  arguments and the result, if any

* A list of all other requirements (other packages or the Tcl version?)

For a maintainer of the code, additional information would include:

* A list of all variables (local to the namespace and global) that are
  used in the various procedures

* The contents of each source file (so where does each procedure live?)

* Detailed maintenance issues that have been written down in comments in the
  code

A possible structure in which all this information can be stored and
retrieved is sketched below:

| program:
|    version
|    source files (list of)
|    packages (list of)
|    procedures (list of)
|    command-line arguments:
|       description of each option and the values (if any)
|       associated with it
|       description of other arguments (such as file names)
| source files:
|    packages (list of)
|    procedures (list of)
| packages:
|    package A:
|       description
|       version
|       requirements
|          Tcl-version
|          packages that are required
|       local and global variables:
|          variable D:
|             used by which procedures?
|          variable E:
|             used by which procedures?
|          ...
|       procedures:
|          procedure F:
|             description
|             exported or not
|             arguments:
|                argument G:
|                   description
|                argument H:
|                   description
|                ...
|             result:
|                description
|          procedure I:
|             ...

Except for the descriptions, all these items can - at least in principle
be extracted automatically. So, even though the programmer has been too
lazy to describe his/her procedures in detail, some information can be
retrieved about the use of global data for instance and the complexity
of the argument lists.

Note that as far as the three methods of organisation is concerned,
there is no attempt to define a practical relationship between them.

To refer to the example above:

| procedure: pkg_compareExtension
|    description:
|       "Used internally by pkg_mkIndex to compare the extension of a file to
|       a given extension. On Windows, it uses a case-insensitive comparison
|       because the file system can be file insensitive."
|    arguments:
|       argument fileName:
|          description:
|             "name of a file whose extension is compared"
|       argument ext:
|          description:
|             "(optional) The extension to compare against; you must
|             provide the starting dot.
|             Defaults to [info sharedlibextension]"
|    result:
|       description:
|          "Returns 1 if the extension matches, 0 otherwise"

By adopting a tree structure to represent the information extracted from
the source code, one can be as flexible as probably needed. For instance,
suppose one would like to extract certain metrics, like the number of
lines or the cyclometric complexity. This could then be an additional
node in the subtree for the command procedure, besides the list of arguments,
the result and the description.

~ Copyright

This document is placed in the public domain.
Deleted tip/41.tip.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418


































































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TIP:            41
Title:          Paned Window Tk Widget
Version:        $Revision: 1.12 $
Author:         Eric Melski <[email protected]>
State:          Accepted
Type:           Project
Vote:           Done
Created:        04-Jul-2001
Post-History:   
Keywords:       widget,tk,panedwindow
Tcl-Version:    8.4a2

~ Abstract

This TIP proposes a C-based paned window widget for inclusion in the
Tk core.  A paned window consists of one or more vertical or
horizontal "panes", each pair separated by a movable "sash" and each
containing one widget, called a "slave".  Paned windows are common in
modern graphical user interfaces and should therefore be provided
directly by the Tk core.  Examples of the widget can be found in
Windows Explorer; Netscape Messenger; many email clients; and
virtually every graphical World Wide Web browser.

~ Rationale

Tk has long lagged other graphical toolkits in terms of the selection
of widgets provided by the toolkit.  In order to keep Tk vibrant,
useful, and relevant, it is imperative that the widget set be enhanced
with widgets which have become commonplace in modern graphical user
interfaces.  One such widget is the paned window widget.  A widget
that makes it easy to create robust paned windows should be included
with Tk.

This paned window widget could be implemented in C or in Tcl; in fact,
several Tcl-based paned window widgets already exist.  However, these
each have quirks, mostly caused by the inability to completely manage
the geometry of Tk windows from Tcl (i.e. there is no way to make
calls to things like ''Tk_MaintainGeometry'' or
''Tk_ManageGeometry'').  This issue could possibly be addressed by the
creation of a proper megawidget system for Tk, but that goal seems
very far from reality right now.  If we wait for that system before
creating new widgets, it may be too late.  In addition, megawidget
implementations suffer from "widget bloat" - each paned window widget
corresponds to, typically two widgets, plus two or more widgets for
each pane after the first.  For a Motif-style paned window with two
panes, this means five widgets are created (one frame for the paned
window container widget; one frame for each pane; one frame for the
sash; one frame for the sash handle).  Even assuming the existence of
a proper megawidget system, we may not be able to address the widget
bloat issue with a megawidget.

A C-based paned window implementation will be able to address both of
these issues, and should be more robust, reliable, and lightweight.  A
C implementation will be able to access Tk's geometry management
functions.  Also, it will require only one widget for each paned window,
regardless of how many panes are in the window.

One obvious argument is that this widget could easily be distributed
as an extension, and need not be included directly in the Tk core.
However, extension widget libraries have been largely unsuccessful in
winning over users.  Developers are reluctant to use those extension
widgets because they cannot rely on their presence in an end-user's
system, and because of concerns of version incompatibilities between
the extension and the core.  Users are reluctant to take on the
responsibility of maintaining the extension in addition to the core.
If this widget is to be truly useful to the Tk community and not just
a programming exercise for the author, it must be included in the Tk core.

In addition, Tk should be a full-featured widget toolkit on its own.
Other popular GUI toolkits are ready out-of-the-box to create
sophisticated, modern applications.  Tk should be as well, and should
not require the procurement of additional extensions to provide what
are truly fundamental widgets in a modern GUI toolkit.  By all means,
esoteric widgets should be left to the extensions, but core widgets
belong in the core.  This question could be made irrelevant with the
introduction of a proper "Batteries Included" distribution, but like
the proper megawidget system, this seems like a goal far from reality
at this time.

Another possibility is to distribute the widget with the core, but have it placed in a separate package and namespace.  This provides the same level of availability as direct inclusion in the core, but does not actually make the widget part of Tk directly.  There are two possible arguments in favor of this approach.  First, since this widget will be in its own namespace, future panedwindow widgets could be included without name conflicts.  However, if each widget is put in its own namespace, the name conflict has not actually been resolved.  The point of contention has simply been moved from the global command space to the global namespace space.  Namespaces make sense when grouping blocks of related functions and data, but widgets have only one command.  It's just as easy to pick a unique command name as a unique namespace name.  The second possible advantage is that the widget could be loaded on demand, rather than automatically being pulled in with Tk.  However, most machines that Tk runs on use a virtual memory system.  Thus, 
only those pages/widgets that are actually used will be resident in memory.  The benefit of incorporating this widget into the Tk distribution in this manner seem marginal.

#image:41example Example Panedwindow Widget

~ Specification

The manual entry for the paned window widget is included here:

|NAME
|       panedwindow - Create and manipulate panedwindow widgets
|
|SYNOPSIS
|       panedwindow pathName ?options?
|
|STANDARD OPTIONS
|       -background           -height              -width
|       -borderwidth          -orient
|       -cursor               -relief
|
|       See  the  options manual entry for details on the standard
|       options.
|
|WIDGET-SPECIFIC OPTIONS
|       Command-Line Name:-handlepad
|       Database Name:  handlePad
|       Database Class: HandlePad
|
|              When sash handles are drawn, specifies the distance
|              from  the top or left end of the sash (depending on
|              the orientation of the widget) at which to draw the
|              handle.  May be any value accepted by Tk_GetPixels.
|
|       Command-Line Name:-handlesize
|       Database Name:  handleSize
|       Database Class: HandleSize
|
|              Specifies the side length of a sash  handle.   Han-
|              dles are always drawn as squares.  May be any value
|              accepted by Tk_GetPixels.
|
|       Command-Line Name:-opaqueresize
|       Database Name:  opaqueResize
|       Database Class: OpaqueResize
|
|              Specifies whether panes should be resized as a sash
|              is  moved (true), or if resizing should be deferred
|              until the sash is placed (false).
|
|       Command-Line Name:-sashcursor
|       Database Name:  sashCursor
|       Database Class: SashCursor
|
|              Mouse cursor to use when over  a  sash.   If  null,
|              sb_h_double_arrow   will  be  used  for  horizontal
|              panedwindows, and sb_v_double_arrow  will  be  used
|              for vertical panedwindows.
|
|       Command-Line Name:-sashpad
|       Database Name:  sashPad
|       Database Class: SashPad
|
|              Specifies  the  amount  of padding to leave of each
|              side of a sash.   May  be  any  value  accepted  by
|              Tk_GetPixels.
|
|       Command-Line Name:-sashrelief
|       Database Name:  sashRelief
|       Database Class: SashRelief
|
|              Relief  to  use when drawing a sash.  May be any of
|              the standard Tk relief values.
|
|       Command-Line Name:-sashwidth
|       Database Name:  sashWidth
|       Database Class: SashWidth
|
|              Specifies the width of each sash.  May be any value
|              accepted by Tk_GetPixels.
|
|       Command-Line Name:-showhandle
|       Database Name:  showHandle
|       Database Class: ShowHandle
|
|              Specifies whether or not sash handles should be shown.
|              May be any valid Tcl boolean value.
|
|DESCRIPTION
|       The panedwindow command creates a new window (given by the
|       pathName argument) and makes it into a panedwindow widget.
|       Additional  options,  described above, may be specified on
|       the command line or in the option  database  to  configure
|       aspects  of the panedwindow such as its default background
|       color and relief.  The  panedwindow  command  returns  the
|       path name of the new window.
|
|       A   panedwindow  widget  contains  any  number  of  panes,
|       arranged horizontally  or  vertically,  according  to  the
|       value  of the -orient option.  Each pane contains one wid-
|       get, and each pair of panes is  separated  by  a  moveable
|       (via mouse movements) sash.  Moving a sash causes the wid-
|       gets on either side of the sash to be resized.
|
|WIDGET COMMAND
|       The panedwindow command creates a new  Tcl  command  whose
|       name  is  the  same  as the path name of the panedwindow's
|       window.  This command may be used to invoke various opera-
|       tions on the widget.  It has the following general form:
|              pathName option ?arg arg ...?
|       PathName  is the name of the command, which is the same as
|       the panedwindow widget's path name.  Option and  the  args
|       determine  the exact behavior of the command.  The follow-
|       ing commands are possible for panedwindow widgets:
|
|       pathName add slave ?slave ...? ?option value ...?
|              Add one or more slaves to the panedwindow, each  in
|              a  separate  pane.   The  arguments  consist of the
|              names of one or  more  slave  windows  followed  by
|              pairs  of  arguments that specify how to manage the
|              slaves.  Option may have any of the values accepted
|              by the configure subcommand.
|
|       pathName cget option
|              Returns  the  current  value  of  the configuration
|              option given by option.  Option may have any of the
|              values accepted by the panedwindow command.
|
|       pathName configure ?option? ?value option value ...?
|              Query  or  modify  the configuration options of the
|              widget.  If no option is specified, returns a  list
|              describing  all  of the available options for path-
|              Name (see Tk_ConfigureInfo for information  on  the
|              format  of this list).  If option is specified with
|              no value, then the command returns a list  describ-
|              ing the one named option (this list will be identi-
|              cal to  the  corresponding  sublist  of  the  value
|              returned  if  no  option  is specified).  If one or
|              more option-value pairs  are  specified,  then  the
|              command modifies the given widget option(s) to have
|              the given  value(s);   in  this  case  the  command
|              returns an empty string. Option may have any of the
|              values accepted by the panedwindow command.
|
|       pathName forget slave ?slave ...?
|              Remove the pane containing slave from the panedwin-
|              dow.   All  geometry  management  options for slave
|              will be forgotten.
|
|       pathName identify x y
|              Identify the panedwindow component  underneath  the
|              point  given by x and y, in window coordinates.  If
|              the point is over a sash  or  a  sash  handle,  the
|              result  is  a two element list containing the index
|              of the  sash  or  handle,  and  a  word  indicating
|              whether  it  is over a sash or a handle, such as {0
|              sash} or {2 handle}.  If  the  point  is  over  any
|              other  part  of  the  panedwindow, the result is an
|              empty list.
|
|       pathName proxy ?args?
|              This command is used to query and change the  posi-
|              tion  of  the sash proxy, used for rubberband-style
|              pane resizing. It can take  any  of  the  following
|              forms:
|
|              pathName proxy coord
|                     Return a list containing the x and y coordi-
|                     nates of the most recent proxy location.
|
|              pathname proxy forget
|                     Remove the proxy from the display.
|
|              pathName proxy place x y
|                     Place  the  proxy  at  the  given  x  and  y
|                     coordinates.
|
|       pathName sash ?args?
|              This  command is used to query and change the posi-
|              tion of sashes in the panedwindow.  It can take any
|              of the following forms:
|
|              pathName sash coord index
|                     Return  the  current x and y coordinate pair
|                     for the sash given by index.  Index must  be
|                     an  integer  between  0  and 1 less than the
|                     number of slaves in  the  panedwindow.   The
|                     coordinates  given are those of the top left
|                     corner of the region  containing  the  sash.
|                     pathName  sash dragto index x y This command
|                     computes the difference  between  the  given
|                     coordinates and the coordinates given to the
|                     last sash coord command for the given  sash.
|                     It then moves that sash the computed differ-
|                     ence.  The return value is the empty string.
|
|              pathName sash mark index x y
|                     Records x and y for the sash given by index;
|                     used in conjunction with later  dragto  com-
|                     mands to move the sash.
|
|              pathName sash place index x y
|                     Place  the  sash given by index at the given
|                     coordinates.
|
|       pathName slavecget slave option
|              Query a management option for slave.  Option may be
|              any value allowed by the slaveconfigure subcommand.
|
|       pathName slaveconfigure slave ?option? ?value option value
|       ...?
|              Query  or  modify the management options for slave.
|              If no option is specified, returns a list  describ-
|              ing  all of the available options for pathName (see
|              Tk_ConfigureInfo for information on the  format  of
|              this  list).  If option is specified with no value,
|              then the command returns a list describing the  one
|              named  option  (this  list will be identical to the
|              corresponding sublist of the value returned  if  no
|              option  is specified).  If one or more option-value
|              pairs are specified, then the command modifies  the
|              given  widget option(s) to have the given value(s);
|              in this case the command returns an  empty  string.
|              The following options are supported:
|
|              -after slave
|                     Insert  the slave after the slave specified.
|                     slave should be the name of a window already
|                     managed by pathName.
|
|              -before slave
|                     Insert the slave before the slave specified.
|                     slave should be the name of a window already
|                     managed by pathName.
|
|              -height size
|                     Specify  a height for the slave.  The height
|                     will be the outer  dimension  of  the  slave
|                     including its border, if any.  If size is an
|                     empty string, or if -height  is  not  speci-
|                     fied,  then  the height requested internally
|                     by the slave will  be  used  initially;  the
|                     height may later be adjusted by the movement
|                     of sashes in the panedwindow.  Size  may  be
|                     any value accepted by Tk_GetPixels.
|
|              -minsize n
|                     Specifies  that the size of the slave cannot
|                     be made less than n.  This  constraint  only
|                     affects  the size of the widget in the paned
|                     dimension -- the x dimension for  horizontal
|                     panedwindows,  the  y dimension for vertical
|                     panedwindows.  May be any value accepted  by
|                     Tk_GetPixels.
|
|              -padx n
|                     Specifies  a  non-negative  value indicating
|                     how much extra space to leave on  each  side
|                     of  the slave in the X-direction.  The value
|                     may  have  any  of  the  forms  accepted  by
|                     Tk_GetPixels.
|
|              -pady n
|                     Specifies  a  non-negative  value indicating
|                     how much extra space to leave on  each  side
|                     of  the slave in the Y-direction.  The value
|                     may  have  any  of  the  forms  accepted  by
|                     Tk_GetPixels.
|
|              -sticky style
|                     If   a  slave's  pane  is  larger  than  the
|                     requested  dimensions  of  the  slave,  this
|                     option  may be used to position (or stretch)
|                     the slave within  its  pane.   Style   is  a
|                     string  that  contains  zero  or more of the
|                     characters n, s, e or  w.   The  string  can
|                     optionally  contains  spaces  or commas, but
|                     they are ignored.  Each letter refers  to  a
|                     side  (north, south, east, or west) that the
|                     slave will "stick" to.  If both n and s  (or
|                     e  and  w)  are specified, the slave will be
|                     stretched to  fill  the  entire  height  (or
|                     width) of its cavity.
|
|              -width size
|                     Specify  a  width  for the slave.  The width
|                     will be the outer  dimension  of  the  slave
|                     including its border, if any.  If size is an
|                     empty string, or if -width is not specified,
|                     then  the  width requested internally by the
|                     slave will be used initially; the width  may
|                     later  be adjusted by the movement of sashes
|                     in the panedwindow.  Size may be  any  value
|                     accepted by Tk_GetPixels.
|
|       pathName slaves
|              Returns  an  ordered list of the widgets managed by
|              pathName.
|
|
|RESIZING PANES
|       A pane is resized by grabbing the sash (or sash handle  if
|       present)  and  dragging  with  the  mouse.  This is accom-
|       plished via mouse motion bindings on the widget.   When  a
|       sash  is moved, the sizes of the panes on each side of the
|       sash, and thus the widgets in those panes, are adjusted.
|
|       When a pane is resized from outside (eg, it is  packed  to
|       expand  and fill, and the containing toplevel is resized),
|       space is added to the final (rightmost or bottommost) pane
|       in the window.

~ Reference Implementation

The widget described here has already been implemented, with
documentation and a full test suite.  The widget is included with the
Vu widget extension, part of the ''tktable'' SourceForge project at
http://tktable.sourceforge.net

~ Notes

Suggestions for possible future enhancements:

 * Allow specification of a weight for each pane, similar to the -weight option supported by
grid, to be used when allocating space from a resize to panes in the
widget.

 * Allow a bindable image to be placed on the window sash, a la 
Netscape's Messenger, or Java Swing, to allow one-click expand and
collapse of the pane.

 * Integrate with the -setgrid option such that if a pane contains
a -setgrided widget, the sash can only be moved in grid size steps.

None of these are prohibited by the current design, and could be 
implemented at a later date as enhancements to the widget.

~ Copyright

This document has been placed in the public domain.
Deleted tip/41example.eps.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761

































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
%!PS-Adobe-3.0 EPSF-3.0
%%Creator: (ImageMagick)
%%Title: (41example.eps)
%%CreationDate: (Fri Jul  6 09:24:18 2001)
%%BoundingBox: 0 0 217 157
%%DocumentData: Clean7Bit
%%LanguageLevel: 1
%%Pages: 0
%%EndComments

%%BeginDefaults
%%PageOrientation: Portrait
%%EndDefaults

%%BeginProlog
%
% Display a color image.  The image is displayed in color on
% Postscript viewers or printers that support color, otherwise
% it is displayed as grayscale.
%
/buffer 512 string def
/byte 1 string def
/color_packet 3 string def
/pixels 768 string def

/DirectClassPacket
{
  %
  % Get a DirectClass packet.
  %
  % Parameters:
  %   red.
  %   green.
  %   blue.
  %   length: number of pixels minus one of this color (optional).
  %
  currentfile color_packet readhexstring pop pop
  compression 0 gt
  {
    /number_pixels 3 def
  }
  {
    currentfile byte readhexstring pop 0 get
    /number_pixels exch 1 add 3 mul def
  } ifelse
  0 3 number_pixels 1 sub
  {
    pixels exch color_packet putinterval
  } for
  pixels 0 number_pixels getinterval
} bind def

/DirectClassImage
{
  %
  % Display a DirectClass image.
  %
  systemdict /colorimage known
  {
    columns rows 8
    [
      columns 0 0
      rows neg 0 rows
    ]
    { DirectClassPacket } false 3 colorimage
  }
  {
    %
    % No colorimage operator;  convert to grayscale.
    %
    columns rows 8
    [
      columns 0 0
      rows neg 0 rows
    ]
    { GrayDirectClassPacket } image
  } ifelse
} bind def

/GrayDirectClassPacket
{
  %
  % Get a DirectClass packet;  convert to grayscale.
  %
  % Parameters:
  %   red
  %   green
  %   blue
  %   length: number of pixels minus one of this color (optional).
  %
  currentfile color_packet readhexstring pop pop
  color_packet 0 get 0.299 mul
  color_packet 1 get 0.587 mul add
  color_packet 2 get 0.114 mul add
  cvi
  /gray_packet exch def
  compression 0 gt
  {
    /number_pixels 1 def
  }
  {
    currentfile byte readhexstring pop 0 get
    /number_pixels exch 1 add def
  } ifelse
  0 1 number_pixels 1 sub
  {
    pixels exch gray_packet put
  } for
  pixels 0 number_pixels getinterval
} bind def

/GrayPseudoClassPacket
{
  %
  % Get a PseudoClass packet;  convert to grayscale.
  %
  % Parameters:
  %   index: index into the colormap.
  %   length: number of pixels minus one of this color (optional).
  %
  currentfile byte readhexstring pop 0 get
  /offset exch 3 mul def
  /color_packet colormap offset 3 getinterval def
  color_packet 0 get 0.299 mul
  color_packet 1 get 0.587 mul add
  color_packet 2 get 0.114 mul add
  cvi
  /gray_packet exch def
  compression 0 gt
  {
    /number_pixels 1 def
  }
  {
    currentfile byte readhexstring pop 0 get
    /number_pixels exch 1 add def
  } ifelse
  0 1 number_pixels 1 sub
  {
    pixels exch gray_packet put
  } for
  pixels 0 number_pixels getinterval
} bind def

/PseudoClassPacket
{
  %
  % Get a PseudoClass packet.
  %
  % Parameters:
  %   index: index into the colormap.
  %   length: number of pixels minus one of this color (optional).
  %
  currentfile byte readhexstring pop 0 get
  /offset exch 3 mul def
  /color_packet colormap offset 3 getinterval def
  compression 0 gt
  {
    /number_pixels 3 def
  }
  {
    currentfile byte readhexstring pop 0 get
    /number_pixels exch 1 add 3 mul def
  } ifelse
  0 3 number_pixels 1 sub
  {
    pixels exch color_packet putinterval
  } for
  pixels 0 number_pixels getinterval
} bind def

/PseudoClassImage
{
  %
  % Display a PseudoClass image.
  %
  % Parameters:
  %   class: 0-PseudoClass or 1-Grayscale.
  %
  currentfile buffer readline pop
  token pop /class exch def pop
  class 0 gt
  {
    currentfile buffer readline pop
    token pop /depth exch def pop
    /grays columns 8 add depth sub depth mul 8 idiv string def
    columns rows depth
    [
      columns 0 0
      rows neg 0 rows
    ]
    { currentfile grays readhexstring pop } image
  }
  {
    %
    % Parameters:
    %   colors: number of colors in the colormap.
    %   colormap: red, green, blue color packets.
    %
    currentfile buffer readline pop
    token pop /colors exch def pop
    /colors colors 3 mul def
    /colormap colors string def
    currentfile colormap readhexstring pop pop
    systemdict /colorimage known
    {
      columns rows 8
      [
        columns 0 0
        rows neg 0 rows
      ]
      { PseudoClassPacket } false 3 colorimage
    }
    {
      %
      % No colorimage operator;  convert to grayscale.
      %
      columns rows 8
      [
        columns 0 0
        rows neg 0 rows
      ]
      { GrayPseudoClassPacket } image
    } ifelse
  } ifelse
} bind def

/DisplayImage
{
  %
  % Display a DirectClass or PseudoClass image.
  %
  % Parameters:
  %   x & y translation.
  %   x & y scale.
  %   label pointsize.
  %   image label.
  %   image columns & rows.
  %   class: 0-DirectClass or 1-PseudoClass.
  %   compression: 0-RunlengthEncodedCompression or 1-NoCompression.
  %   hex color packets.
  %
  gsave
  currentfile buffer readline pop
  token pop /x exch def
  token pop /y exch def pop
  x y translate
  currentfile buffer readline pop
  token pop /x exch def
  token pop /y exch def pop
  currentfile buffer readline pop
  token pop /pointsize exch def pop
  /Helvetica findfont pointsize scalefont setfont
  x y scale
  currentfile buffer readline pop
  token pop /columns exch def
  token pop /rows exch def pop
  currentfile buffer readline pop
  token pop /class exch def pop
  currentfile buffer readline pop
  token pop /compression exch def pop
  class 0 gt { PseudoClassImage } { DirectClassImage } ifelse
  grestore
} bind def
%%EndProlog
%%Page:  1 1
%%PageBoundingBox: 0 0 218 158
userdict begin
%%BeginData:
DisplayImage
0 0
218 158
12
218 158
1
0
0
256
f8fcf8
808080
d8d8d8
c89860
c89868
c86430
c83400
c86468
c86460
c03000
c03400
c03408
c83000
c86400
f89800
f89860
f89868
c83430
c89800
f8fc00
f8c800
c83408
c83008
c06400
f8cc00
c83438
c06438
c06430
c86438
f8cc98
f8c8c8
c09800
f89898
c8c8f8
c0c8f8
6098c8
003490
003498
303498
c89890
f8fcc8
003098
003090
909890
306490
906498
90c8c0
903030
9098c8
683430
6098c0
303060
303490
90c8c8
983430
303468
906460
6898c8
c0c8c8
683030
683468
303460
983400
303098
6864c8
6064c8
c03430
c8c8c8
903400
683060
303068
98c8c8
903430
f8ccc0
f89890
9098c0
603430
f8ccc8
c83030
683438
c09860
306498
6898c0
986468
386490
303090
906430
9898c8
c89898
603468
603030
383498
906468
986498
3064c8
603460
603060
383468
c8ccf8
903000
c8fcf8
683460
c098c8
903438
c8ccc8
983030
f8c8c0
983438
c09868
686490
986490
683068
c06468
606490
383460
083498
686498
906490
c06460
606498
c0ccf8
603068
983000
f8c898
606468
90ccf8
90c8f8
903038
6864c0
f8fcc0
c898c0
986460
c0ccc8
9898c0
383068
686460
f8c890
f8cc90
f09898
c03438
383490
603438
98ccc0
c8ccc0
98c8c0
3064c0
3864c8
98ccc8
386498
6064c0
c8c8c0
3864c0
c0fcf8
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
00ff00b20100000102660004026901010001026600000202010002690101000102660000
0202010002690101000102250300040003000503060e05000229000002020100022a0300
040003000503060e05000227010100010214030007000800050306080900060009000600
0a000b0006000a000900060009000a000c000a000900060009000a000c000a0009000600
090006020300022600000202010002190300070008000503060809000600090006000a00
0b0006000a000900060009000a000c000a000900060009000a000c000a00090006000900
0602030002240101000102090609090006000a0006000a000b0006000a00090006000900
0a000c000a00090006000a0006010a0006000c000600090006010a0006010a0006010a00
06010a0006010a0006000a000c000a000c00060005000224000002020100020e06090900
06000a0006000a000b0006000a000900060009000a000c000a00090006000a0006010a00
06000c000600090006010a0006010a0006010a0006010a0006010a0006000a000c000a00
0c00060005000222010100010209060009000a000c000a000900060009000a0006010a00
0c000a000c000600090006010a0006000d000a00060109000600090006000c000a000e01
0d000a000c000600090006000c000a000c000600090006000c000a000c0006000c000a00
06000a0006000a000602040002060f00100003000503110206060209000002020100020e
060009000a000c000a000900060009000a0006010a000c000a000c000600090006010a00
06000d000a00060109000600090006000c000a000e010d000a000c000600090006000c00
0a000c000600090006000c000a000c0006000c000a0006000a0006000a00060204000206
0f0010000300050311020606020701010001020906020a0006010a0006000c000a000c00
06000a0006010a00060109001200130014000600090006030a000d0013030d000a000601
0a0006010a0006010a0006010a0006000a0006000c000a000c000a000c000a0009000606
0c000600090006000a0015000a0116000a000900060009000a000c000a00090006000209
000002020100020e06020a0006010a0006000c000a000c0006000a0006010a0006010900
1200130014000600090006030a000d0013030d000a0006010a0006010a0006010a000601
0a0006000a0006000c000a000c000a000c000a00090006060c000600090006000a001500
0a0116000a000900060009000a000c000a00090006000207010100010209060009000600
090006000c0006000a0006010a0006000c000a000c00060009000600120013010d000a00
060109000a000c000600130414000600090006000c000a000c000600090006000c000a00
0c000a000c0006000a0006010a0006000a0006010a000c000a000900060009000a000600
0a000601090006000c0006000a0006010a0006010a0006010a0002080007020c06000900
0600090006000c0006000a0006010a0006000c000a000c00060009000600120013010d00
0a00060109000a000c000600130414000600090006000c000a000c000600090006000c00
0a000c000a000c0006000a0006010a0006000a0006010a000c000a000900060009000a00
06000a000601090006000c0006000a0006010a0006010a0006010a000207010100010209
06000a0006010a00060009000600090006000c000a0006010a0006010a00130114000a00
06000c000a0006010a0014001302140017000d000a0006000a0006010a0006010a000601
0a0006000a000c000600090006000c000a000c000600090006000a0006010a0006010900
0600090006010a0006000a000c000a000c000600090006000c000a000c00060002080000
02050100020c06000a0006010a00060009000600090006000c000a0006010a0006010a00
130114000a0006000c000a0006010a0014001302140017000d000a0006000a0006010a00
06010a0006010a0006000a000c000600090006000c000a000c000600090006000a000601
0a00060109000600090006010a0006000a000c000a000c000600090006000c000a000c00
0600020701010001020906000c000a000c000a0006010a0006000a000601090006000c00
0a000c00120013010d0006000a000601090006000d001302170006010a0006000c000600
090006000c000a000c000600090006000c0006010a0006010a0006010a0006010a000c00
0600090006000c000a0006020a000c000a000c0006000a0006010a0006010a0006010a00
0208000002050100020c06000c000a000c000a0006010a0006000a000601090006000c00
0a000c00120013010d0006000a000601090006000d001302170006010a0006000c000600
090006000c000a000c000600090006000c0006010a0006010a0006010a0006010a000c00
0600090006000c000a0006020a000c000a000c0006000a0006010a0006010a0006010a00
020701010001020911000a0006010c000a000c0006000c000600090006010a0006010a00
1400130014000a000c000600090006010900180013010d0006000a0006000c000a000600
0a0006000a0006010a0006010a000600090006000900060009000600090006000c000a00
0c0006000a0006010a00060109000600090006020a0006000c000a000c00060009000600
0c000a000c0006000208000002050100020c11000a0006010c000a000c0006000c000600
090006010a0006010a001400130014000a000c000600090006010900180013010d000600
0a0006000c000a0006000a0006000a0006010a0006010a00060009000600090006000900
0600090006000c000a000c0006000a0006010a00060109000600090006020a0006000c00
0a000c000600090006000c000a000c000600020701010001020911000c000a0006000a00
06000a0006000a0006000a00060009000600090006000c00180013001200090006000a00
06000a00060012001301170006000a000c000a000601090006000c000600090006000c00
0a000c000a0006000a0006010a0006020a0006010a0006000c000a000c00060009000601
0a0006000a000c000a000c000a0006010a0006010a0006010a0005000208000002050100
020c11000c000a0006000a0006000a0006000a0006000a00060009000600090006000c00
180013001200090006000a0006000a00060012001301170006000a000c000a0006010900
06000c000600090006000c000a000c000a0006000a0006010a0006020a0006010a000600
0c000a000c000600090006010a0006000a000c000a000c000a0006010a0006010a000601
0a000500020701010001020919000a000c000a000c00060009000600090006000c000a00
06020a0006001301170006010c000a000c000a0013010e000c000a000602090006010a00
06000a0006000a0006010a000c0006000c000a000c000600090006000900060009000600
0c000a0006010a0006010a000c0006000c000a0006010a000600090006000c000a000c00
0600090006000c001a000208000002050100020c19000a000c000a000c00060009000600
090006000c000a0006020a0006001301170006010c000a000c000a0013010e000c000a00
0602090006010a0006000a0006000a0006010a000c0006000c000a000c00060009000600
09000600090006000c000a0006010a0006010a000c0006000c000a0006010a0006000900
06000c000a000c000600090006000c001a000207010100010209050006000a0006000a00
06010a0006000a00060109000600090006000900130014000600090006000a0006011200
13010c000a000600090006000a0006000a000c000600090006000c000600090006010a00
06000a0006000a0006010a0006020a000601090006000c000a000c0006000a0006000a00
0600090006000c0006010a0006010a0006010a00060008000208000002050100020c0500
06000a0006000a0006010a0006000a000601090006000900060009001300140006000900
06000a000601120013010c000a000600090006000a0006000a000c000600090006000c00
0600090006010a0006000a0006000a0006010a0006020a000601090006000c000a000c00
06000a0006000a000600090006000c0006010a0006010a0006010a000600080002070101
0001020905000a000c0006000c000a000c0006000c000600090006010a00060213000e00
06000a0006000c000a000c0014001300170006020a000c000600090006000a0006010a00
06000a00060009000600090006000c001b0004001b000c00060009000600090006000900
06010a0006010a000600090006000c000a0006010a010c000600090006000c000a000c00
06000a000700020800000106020c05000a000c0006000c000a000c0006000c0006000900
06010a00060213000e0006000a0006000c000a000c0014001300170006020a000c000600
090006000a0006010a0006000a00060009000600090006000c001b0004001b000c000600
0900060009000600090006010a0006010a000600090006000c000a0006010a010c000600
090006000c000a000c0006000a00070002070101000102091c0006000a0006000a000600
0a0006000a0006000a000600090006000c000a000c001300170006000c000a0006000a00
0d001300140006000a000c000a0006000a0006020c000a000c000600090006020a000500
1d0000031e0006000a0006030a000c000600090006000c000a0006000a00060109000600
0c0006000a0006010a0006010a0006000c00020a000002020100020e1c0006000a000600
0a0006000a0006000a0006000a000600090006000c000a000c001300170006000c000a00
06000a000d001300140006000a000c000a0006000a0006020c000a000c00060009000602
0a0005001d0000031e0006000a0006030a000c000600090006000c000a0006000a000601
090006000c0006000a0006010a0006010a0006000c00020801010001020905000a000c00
0a000c00060009000600090006000c000a0006010a0006000a0013000d000a0006010900
06000e0013001f000c0006000a000c0006000c000a000c000a0006000a0006000a000600
0c000a000c00070000061e00060009000600090006010a0006010a0006010c0006000900
06010a0006000a000c000a000c000600090006000c000a000600020a000002020100020e
05000a000c000a000c00060009000600090006000c000a0006010a0006000a0013000d00
0a000601090006000e0013001f000c0006000a000c0006000c000a000c000a0006000a00
06000a0006000c000a000c00070000061e00060009000600090006010a0006010a000601
0c000600090006010a0006000a000c000a000c000600090006000c000a00060002080101
00010209050006000a0006000a0006010a0006000a000601090006000c000a000c001800
0c000a0006000a000601130106000a0006010a0006000a0006000a0006000c000a000c00
06000a000601200000042101000103000a000601090006000c000a000c00060009000600
0a0006000a00060009000600090006020a0006010a0006010a00020a000002020100020e
050006000a0006000a0006010a0006000a000601090006000c000a000c0018000c000a00
06000a000601130106000a0006010a0006000a0006000a0006000c000a000c0006000a00
0601200000042101000103000a000601090006000c000a000c000600090006000a000600
0a00060009000600090006020a0006010a0006010a000208010100010209040009000600
0c000600090006000c0006000c000a0006010a0006010a00140006000a000c0006000900
0d00130014000c000600090006000c000a000c0006000c000a0006010a000c0006000900
1d000002220023002400250024002600270028000c000a0006010a0006010a0006000a00
0600090006000c000a0006020a000c000a000c000a000c000600090006000c00020a0000
02020100020e0400090006000c000600090006000c0006000c000a0006010a0006010a00
140006000a000c00060009000d00130014000c000600090006000c000a000c0006000c00
0a0006010a000c00060009001d000002220023002400250024002600270028000c000a00
06010a0006010a0006000a000600090006000c000a0006020a000c000a000c000a000c00
0600090006000c000208010100010209030006000a0006000a0006000a0006000a000600
0900060009000600090006000c000e000a0006010a00060014001300170006000a000600
0a0006010a0006000a000600090006010a0006001e000002230024002900240029002400
2a0025002b0005000600090006000c000a000c000600090006020a000601090006000900
06000a0006020a0006010a000600020a000002020100020e030006000a0006000a000600
0a0006000a0006000900060009000600090006000c000e000a0006010a00060014001300
170006000a0006000a0006010a0006000a000600090006010a0006001e00000223002400
29002400290024002a0025002b0005000600090006000c000a000c000600090006020a00
060109000600090006000a0006020a0006010a0006000208010100010209040009000600
090006000c000a000c000a0006010a0006020a000600170006000c000a000c0006001301
0600090006000c000600090006000c000a000c000601090006000c002000000122002c00
24002500240225002400290024002d0006010a0006010a00060109000600090006000900
06010a0006010c000a000c000a000c000a000c0006000900020a000002020100020e0400
09000600090006000c000a000c000a0006010a0006020a000600170006000c000a000c00
060013010600090006000c000600090006000c000a000c000601090006000c0020000001
22002c0024002500240225002400290024002d0006010a0006010a000601090006000900
0600090006010a0006010c000a000c000a000c000a000c00060009000208010100010209
030006000a0006000a0006010a000c000a000c00060009000600090006000c000d000a00
06010a000d001300140006010a0006000a0006000a0006010a0006000a0006000a002000
00012e00250024002900240029002400290024012500240026002f0006000c000a000c00
0600090006000a0006010a0006000a000c000600090006000a0006000a0006020a000601
020a000002020100020e030006000a0006000a0006010a000c000a000c00060009000600
090006000c000d000a0006010a000d001300140006010a0006000a0006000a0006010a00
06000a0006000a00200000012e0025002400290024002900240029002401250024002600
2f0006000c000a000c000600090006000a0006010a0006000a000c000600090006000a00
06000a0006020a000601020801010001020a0c0006000c000600090006030a0006010a00
06000a0006000a0006000900060009000e0013001700060009000600090006000c000600
090006000c000a000c00060007000001300024002a002500240225002400290024002a00
2500310006000a0006010a0006010a000c000a000c0006000c0006000a0006010a000c00
06000c000a000c000a000c000a000c00020a000002020100020f0c0006000c0006000900
06030a0006010a0006000a0006000a0006000900060009000e0013001700060009000600
090006000c000600090006000c000a000c00060007000001300024002a00250024022500
2400290024002a002500310006000a0006010a0006010a000c000a000c0006000c000600
0a0006010a000c0006000c000a000c000a000c000a000c00020801010001020a06000a01
0601090006000900060009000600090006000c0006000a000c0006010a00060014001300
06000a0006020a0006000a0006000a0006010a000500000132002a002500240129002400
2900240225002400330006000c000600090006000c000a000c0006020a0006000a000600
09000600090006010a0006000a0006010a0006001100020a000002020100020f06000a01
0601090006000900060009000600090006000c0006000a000c0006010a00060014001300
06000a0006020a0006000a0006000a0006010a000500000132002a002500240129002400
2900240225002400330006000c000600090006000c000a000c0006020a0006000a000600
09000600090006010a0006000a0006010a0006001100020801010001020a06000c000600
090006000a0006000a0006010a0006010a0006010a000600090006000c00130014000600
0c000a000c000a000c000a000c0006000c000a000c0006001e0000003000240025002400
29002401250024002a0025002a002500340006010a0006010a0006010a00060009000600
09000600090006010a000601090006000c000600090006000c000a001c00020a00000202
0100020f06000c000600090006000a0006000a0006010a0006010a0006010a0006000900
06000c001300140006000c000a000c000a000c000a000c0006000c000a000c0006001e00
0000300024002500240029002401250024002a0025002a002500340006010a0006010a00
06010a0006000900060009000600090006010a000601090006000c000600090006000c00
0a001c00020801010001020a06000a0006000a0006000c000a000c000a000c0006000900
06000c000a000c000a0006010a000d0013000e000a0006000a0006010a0006000a000600
0a0006000a0020000000350024002900240125002400290024012500240025002a003600
0c000a000c000a000c00060009000600090006000a0006010a0006000a000c0006000900
06010a0006000a0006000a0006000c001b00020a000002020100020f06000a0006000a00
06000c000a000c000a000c000600090006000c000a000c000a0006010a000d0013000e00
0a0006000a0006010a0006000a0006000a0006000a002000000035002400290024012500
2400290024012500240025002a0036000c000a000c000a000c0006000900060009000600
0a0006010a0006000a000c000600090006010a0006000a0006000a0006000c001b000208
01010001020a0600090006000c000a0006030a0006010a0006010a000c000a000c000a00
120013001f000c0006000c000a000c0006000c000a000c00060009000500000021002402
290024002a00250024002a0025002a002401310006000a0006020a0006010a0006010c00
0a000c0006000c0006000a0006000d000e0017000c000a000c0006000c000a0006000400
020a000002020100020f0600090006000c000a0006030a0006010a0006010a000c000a00
0c000a00120013001f000c0006000c000a000c0006000c000a000c000600090005000000
21002402290024002a00250024002a0025002a002401310006000a0006020a0006010a00
06010c000a000c0006000c0006000a0006000d000e0017000c000a000c0006000c000a00
06000400020801010001020a06010a000601090006000900060009000600090006000900
06030a0006000e0013000d000a0006000a0006000a0006000a0006000a0006011e000000
2c0025002a0025002400250024012500240125002a0037000c0006000c000a000c000a00
0c000a000c00060009000d000e0014000e000a0006000a000c000a0006000e0013001400
0d000a0006000a0006000a000400020a000002020100020f06010a000601090006000900
06000900060009000600090006030a0006000e0013000d000a0006000a0006000a000600
0a0006000a0006011e0000002c0025002a0025002400250024012500240125002a003700
0c0006000c000a000c000a000c000a000c00060009000d000e0014000e000a0006000a00
0c000a0006000e00130014000d000a0006000a0006000a000400020801010001020a0600
09000600090006000a0006000a0006010a00060209000600090006000c000a0014001300
0c000a000c00060009000600090006000c00060009000400000023002400250024012900
2400290024002900240029002400250006010a0006010a0006020a0006000a000e001302
0e000c000a00060109000600130118000c000a000c0006000c0038002300390002080000
02020100020f060009000600090006000a0006000a0006010a0006020900060009000600
0c000a00140013000c000a000c00060009000600090006000c0006000900040000002300
24002500240129002400290024002900240029002400250006010a0006010a0006020a00
06000a000e0013020e000c000a00060109000600130118000c000a000c0006000c003800
23003900020601010001020a06010a000601090006000c000a000c000600090006000a00
06000a0006000a0006000c00130014000a0006000a0006010a0006000a0006000a000600
28003a00240029002400290024032500240225003b00060009000600090006000c000a00
0c000a000c0006010a001400130114000a0006000900060109000e00130106010a000600
0a003c00240025002400250024000205000002020100020f06010a000601090006000c00
0a000c000600090006000a0006000a0006000a0006000c00130014000a0006000a000601
0a0006000a0006000a00060028003a00240029002400290024032500240225003b000600
09000600090006000c000a000c000a000c0006010a001400130114000a00060009000601
09000e00130106010a0006000a003c0024002500240025002400020301010001020a0600
09000600090006010a0006010a000601090006000c000600090006000a00060013001400
06000c000600090006000c000600090006000c00200000002c00240325002a0025002a00
24002900240029003d0006000a0006010a0006000a0006020a000600090006000e001301
0e000c0006010a000601170013010a000c000a000c00060037002a0025002a0024002900
0205000002020100020f060009000600090006010a0006010a000601090006000c000600
090006000a0006001300140006000c000600090006000c000600090006000c0020000000
2c00240325002a0025002a0024002900240029003d0006000a0006010a0006000a000602
0a000600090006000e0013010e000c0006010a000601170013010a000c000a000c000600
37002a0025002a0024002900020301010001020a06010a0006000a000c00060009000600
0c000a0006010a0006000a0006000c000600090013000e000a0006000a0006000a000600
0a0006000a00060000003500240025002a0025002a002500240025002400250024002500
24003e000c000600090006000c000a000c000a000c000a000c000a0006010e0013011200
0a00060009000600090006011300140006020a0006003d0025002400250024002c000205
000002020100020f06010a0006000a000c000600090006000c000a0006010a0006000a00
06000c000600090013000e000a0006000a0006000a0006000a0006000a00060000003500
240025002a0025002a00250024002500240025002400250024003e000c00060009000600
0c000a000c000a000c000a000c000a0006010e00130112000a0006000900060009000601
1300140006020a0006003d0025002400250024002c00020301010001020a060009000600
0c0006000a0006010a0006000c000a000c000600090006010a0006000d0013000d000a00
0c00060009000600090006000c000a00040000002c002500240025002400250024002a00
25002a002400290024003b000a0006000a0006000a0006020a0006010a0006000c000a00
0e00130117000c000a0006020a000c0013000d000a000c000a000c0006003f0024002a00
25002a0040000205000002020100020f0600090006000c0006000a0006010a0006000c00
0a000c000600090006010a0006000d0013000d000a000c00060009000600090006000c00
0a00040000002c002500240025002400250024002a0025002a002400290024003b000a00
06000a0006000a0006020a0006010a0006000c000a000e00130117000c000a0006020a00
0c0013000d000a000c000a000c0006003f0024002a0025002a004000020301010001020a
06010a0006000a000c000a000c0006000a0006010a000601090006000c000a000d001300
170006000a0006010a0006000a0006000c001e003a002401290024002a00240025002401
2500240137000601090006000c00060009001c001b000600090006000c000a0006000c00
14001300140006020900060009000600170018000c000a0006010a000600250024002500
2400250032000205000002020100020f06010a0006000a000c000a000c0006000a000601
0a000601090006000c000a000d001300170006000a0006010a0006000a0006000c001e00
3a002401290024002a002400250024012500240137000601090006000c00060009001c00
1b000600090006000c000a0006000c001400130014000602090006000900060017001800
0c000a0006010a000600250024002500240025003200020301010001020a060009000600
090006020a000c000600090006000c000a0006010a0006000a000d00130006000c000600
090006000c0006000c000a0005000000410024002500240125002a0025002a0025002a00
25002a0036000c000a000600420004001e000001280006010a0006010a00060014001300
0e000a000c000a0006000a0006010e000d000a000600090006000c000a002a0025002a00
24010206000002020100020f060009000600090006020a000c000600090006000c000a00
06010a0006000a000d00130006000c000600090006000c0006000c000a00050000004100
24002500240125002a0025002a0025002a0025002a0036000c000a000600420004001e00
0001280006010a0006010a000600140013000e000a000c000a0006000a0006010e000d00
0a000600090006000c000a002a0025002a002401020401010001020a1c0006000a000600
0a000c000a0006000a0006010a0006000c000a000c00060009000600170013000a000600
0a0006000a0006000a0006000a00100000002400290024002a0025002400250024022500
24003d0006000a001100430000051b0006000c000a000c000a000c0013010d000a000601
0900060009000600170006000c0006010a00060044002500240125002900020600000202
0100020f1c0006000a0006000a000c000a0006000a0006010a0006000c000a000c000600
09000600170013000a0006000a0006000a0006000a0006000a0010000000240029002400
2a002500240025002402250024003d0006000a001100430000051b0006000c000a000c00
0a000c0013010d000a0006010900060009000600170006000c0006010a00060044002500
240125002900020401010001020a05000a000c0006010a000c0006000c000a000c000600
0a0006010a0006020d0014000600090006000c000a000c000a000c0006001e0030002401
25002400290024002a0025002a0025002a00250045003700460025002400290024004100
4700000104000a0006010a0006001700130014000a00060009000603090006000a000600
0a000c000a000c00480029002400290024010206000002020100020f05000a000c000601
0a000c0006000c000a000c0006000a0006010a0006020d0014000600090006000c000a00
0c000a000c0006001e003000240125002400290024002a0025002a0025002a0025004500
37004600250024002900240041004700000104000a0006010a0006001700130014000a00
060009000603090006000a0006000a000c000a000c004800290024002900240102040101
0001020a050006000a000c000a0006000a0006000a0006000a000c000600090006000c00
0a000c000a00060014000a0006000a0006010a0006010900000040002400290024022500
24002500240125002400250024002500240125002402280000000f000c000a000c000600
0c00120013000e000c0006010a000c000a0006010a000c000a0006020a00360025002401
25002c000206000002020100020f050006000a000c000a0006000a0006000a0006000a00
0c000600090006000c000a000c000a00060014000a0006000a0006010a00060109000000
400024002900240225002400250024012500240025002400250024012500240228000000
0f000c000a000c0006000c00120013000e000c0006010a000c000a0006010a000c000a00
06020a0036002500240125002c00020401010001020a1c000a0006000a000c0006000900
06000c000a0006000a0006010a0006000a0006000a000c000e0006000c00060009000600
0c000a0006000500000024002500240029002400290024002a002400290024002a002500
2a0024002a0025002a0024002900240046004900000020000a0006000a0006000a001400
13000d000a000600090006000a000c000a000c0006000a000c000a000c000a000c004800
290024002900240039000206000002020100020f1c000a0006000a000c00060009000600
0c000a0006000a0006010a0006000a0006000a000c000e0006000c000600090006000c00
0a0006000500000024002500240029002400290024002a002400290024002a0025002a00
24002a0025002a0024002900240046004900000020000a0006000a0006000a0014001300
0d000a000600090006000a000c000a000c0006000a000c000a000c000a000c0048002900
2400290024003900020401010001020a08000600090006000a0006010a0006000c000600
0c000a000c000600090006000c000a000600170006000a0006000a0006000a000c000a00
0400220025002a0024012500240025002400250024002500240125002400250024002500
24002500240036001e0000004a000c000600090006000c00130014000a0006000a000602
0a0006000a0006020a0006010a0031002500240125000207000002020100020f08000600
090006000a0006010a0006000c0006000c000a000c000600090006000c000a0006001700
06000a0006000a0006000a000c000a000400220025002a00240125002400250024002500
2400250024012500240025002400250024002500240036001e0000004a000c0006000900
06000c00130014000a0006000a0006020a0006000a0006020a0006010a00310025002401
2500020501010001020a07000a0006010c000a000c0006000a0006000a0006000a000600
0a0006010a0006010a000c000a000c0006000900060220004b002a002500240029002400
2a002400290024002a0025002a0025002a0025002a002400290024002a0025000c000001
0300090006010a000d0013000d0006000900060009000600090006000c00060009000600
09000600090006000c004c0029002400290024000207000002020100020f07000a000601
0c000a000c0006000a0006000a0006000a0006000a0006010a0006010a000c000a000c00
06000900060220004b002a0025002400290024002a002400290024002a0025002a002500
2a0025002a002400290024002a0025000c0000010300090006010a000d0013000d000600
0900060009000600090006000c0006000900060009000600090006000c004c0029002400
29002400020501010001020a070006000a0006000a0006000a000c000a000c000a000c00
0600090006000c000a000c000a000c0006000a0006000a0006010a000c000a001e004000
24012500240125002401250024012500240225002401250024003400110000011b000600
0a000c000a000e0013000a0006020a0006010a0006000a0006000a0006020a0006003700
2400250024010207000002020100020f070006000a0006000a0006000a000c000a000c00
0a000c000600090006000c000a000c000a000c0006000a0006000a0006010a000c000a00
1e0040002401250024012500240125002401250024022500240125002400340011000001
1b0006000a000c000a000e0013000a0006020a0006010a0006000a0006000a0006020a00
06003700240025002401020501010001020a08000a000c000a000c0006010a0006020a00
06010a0006030a0006000c0006000c000a000c0006000a000c004d002c0025002a002400
290024002900240029002400290024002a0025002a0025002a0025002a0025002a003c00
0700000111000c0006000a00060013000e000c000a000c000a000c000a000c000a000c00
06000900060009000600090006000c0037002a00240029002c000207000002020100020f
08000a000c000a000c0006010a0006020a0006010a0006030a0006000c0006000c000a00
0c0006000a000c004d002c0025002a002400290024002900240029002400290024002a00
25002a0025002a0025002a0025002a003c000700000111000c0006000a00060013000e00
0c000a000c000a000c000a000c000a000c0006000900060009000600090006000c003700
2a00240029002c00020501010001020a040006000a0006000a000c000a000c000a000c00
0a000c000a000c0006000900060009000600090006000a0006000a0006000a0006010a00
28002a00240025002400250024012500240225002401250024022500240025002f004a00
00001e000a0006000a000c000d0013000a0006010a0006020a0006000a0006020a000601
0a0006003d0025002400250040000207000002020100020f040006000a0006000a000c00
0a000c000a000c000a000c000a000c0006000900060009000600090006000a0006000a00
06000a0006010a0028002a00240025002400250024012500240225002401250024022500
240025002f004a0000001e000a0006000a000c000d0013000a0006010a0006020a000600
0a0006020a0006010a0006003d002500240025004000020501010001020b0c0006000c00
0a0006010a0006000a0006020a0006000a0006000a0006010a000c000a000c0006000c00
0a000c0006004300240025002a0024002a0025002a002400290024002900240029002400
2a0025002a0025002a00240106001e0000004a000600090006000a000e010c000a000c00
060009000600090006000c0006000900060009000600090006000c000a003f0024002900
2400020800000202010002100c0006000c000a0006010a0006000a0006020a0006000a00
06000a0006010a000c000a000c0006000c000a000c0006004300240025002a0024002a00
25002a0024002900240029002400290024002a0025002a0025002a00240106001e000000
4a000600090006000a000e010c000a000c00060009000600090006000c00060009000600
09000600090006000c000a003f00240029002400020601010001020b06000a0006010900
06000c000a000c000a000c000a000c000600090006000c000a000c0006000a0006000a00
06000a0006000a0006003a00240125002400250024002500240125002402250024012500
240129003d004e0000011b0006010a000c00140006000a0006000a0006000a0006010a00
06000a0006000a0006020a0006012500240125000208000002020100021006000a000601
090006000c000a000c000a000c000a000c000600090006000c000a000c0006000a000600
0a0006000a0006000a0006003a0024012500240025002400250024012500240225002401
2500240129003d004e0000011b0006010a000c00140006000a0006000a0006000a000601
0a0006000a0006000a0006020a000601250024012500020601010001020b060009000600
0a0006000a0006020a0006010a0006010a0006010a0006000c000600090006000c000a00
0c00060030002a0025002a0025002a00240029002400290024002a0025002a0025002a00
25002a002400250024004f000400000028000600090006010d000e000a000c0006000c00
0a000c000a000c000a000c000600090006000900060009000600090006002a0025002a00
2400020800000202010002100600090006000a0006000a0006020a0006010a0006010a00
06010a0006000c000600090006000c000a000c00060030002a0025002a0025002a002400
29002400290024002a0025002a0025002a0025002a002400250024004f00040000002800
0600090006010d000e000a000c0006000c000a000c000a000c000a000c00060009000600
0900060009000600090006002a0025002a002400020601010001020b0601090006000c00
06000900060009000600090006000c000a000c000600090006000c000a0006000a000600
0a0006010a0006002b00250024022500240125002401250024002500240225002a002500
2a0036001e00000050000601090006000e00090006010a0006030a0006000a0006020a00
06010a0006012500240025002400020800000202010002100601090006000c0006000900
060009000600090006000c000a000c000600090006000c000a0006000a0006000a000601
0a0006002b00250024022500240125002401250024002500240225002a0025002a003600
1e00000050000601090006000e00090006010a0006030a0006000a0006020a0006010a00
06012500240025002400020601010001020b06000a0006000a0006000a0006000a000602
0a0006010a0006010a0006000a000c000600090006000c000a000c0006002d002a002400
2900240029002400290024002a0025002a0024002a0025002a0025002401250024000c00
00011100090006010a000d0006000a000c00060009000600090006000c0006000c000a00
0c000a000c000a000c00060009004800290024002a005100020800000202010002100600
0a0006000a0006000a0006000a0006020a0006010a0006010a0006000a000c0006000900
06000c000a000c0006002d002a0024002900240029002400290024002a0025002a002400
2a0025002a0025002401250024000c0000011100090006010a000d0006000a000c000600
09000600090006000c0006000c000a000c000a000c000a000c0006000900480029002400
2a005100020601010001020b06000c000a000c0006000c000a000c000a000c000a000c00
0a000c000600090006000c000a0006000a0006010a0006010a000c003800250024002500
24012500240125002c00250024002500240025002a0025002a0024003700030000002000
0a0006000a000c0006000a000c0006000a0006000a0006000a0006000a0006000a000600
0a0006020a000601480025002400250052000208000002020100021006000c000a000c00
06000c000a000c000a000c000a000c000a000c000600090006000c000a0006000a000601
0a0006010a000c00380025002400250024012500240125002c0025002400250024002500
2a0025002a00240037000300000020000a0006000a000c0006000a000c0006000a000600
0a0006000a0006000a0006000a0006000a0006020a000601480025002400250052000206
01010001020b06000a0006000a0006000a0006020a0006020a0006010a0006000c000600
0c000a000c000600090006010a005300240025002a0025002a0024002900240054005100
2400290024002a0024002500240025002a0031001e0000000a000c0006010a0006010a00
06000c000a000c000600090006000c000a000c0006000c000a000c000a000c000a000c00
4c00290024010209000002020100021006000a0006000a0006000a0006020a0006020a00
06010a0006000c0006000c000a000c000600090006010a005300240025002a0025002a00
240029002400540051002400290024002a0024002500240025002a0031001e0000000a00
0c0006010a0006010a0006000c000a000c000600090006000c000a000c0006000c000a00
0c000a000c000a000c004c0029002401020701010001020b06000c000a000c000a000c00
0a000c000a000c000a000c000a000c000a000c0006000a0006000a0006000a0006000a00
0600090006014800250024022500240025005500390024022500240025002a0024012500
56000000030006000a000c000a000c000a000c0006000a0006010a0006010a0006010a00
06000a0006000a0006034c002500240029000209000002020100021006000c000a000c00
0a000c000a000c000a000c000a000c000a000c000a000c0006000a0006000a0006000a00
06000a000600090006014800250024022500240025005500390024022500240025002a00
2401250056000000030006000a000c000a000c000a000c0006000a0006010a0006010a00
06010a0006000a0006000a0006034c00250024002900020701010001020b06000a000602
0a0006030a0006010a0006000a000c000a000c000a000c000600090006020a000c004800
2900240029002400290024003d00310057002a0025002a0025002a00240025002a002500
2a0058001e000a000c0006000a0006020a000c000600090006000c000a000c0006000900
0600090006000c000a000c000a000c000a000c0059002a00250024000209000002020100
021006000a0006020a0006030a0006010a0006000a000c000a000c000a000c0006000900
06020a000c0048002900240029002400290024003d00310057002a0025002a0025002a00
240025002a0025002a0058001e000a000c0006000a0006020a000c000600090006000c00
0a000c00060009000600090006000c000a000c000a000c000a000c0059002a0025002400
020701010001020b06000c000a000c000a000c000a000c000a000c000600090006000c00
06010a0006020a00060109000600090006022500240125002400290031005a0057002500
24002500240025002400250024013d001e00050006000a0006000c000a000c000a000600
0a0006010a0006010a0006010a0006000a0006020a0006000a0006003c0024015b000209
000002020100021006000c000a000c000a000c000a000c000a000c000600090006000c00
06010a0006020a00060109000600090006022500240125002400290031005a0057002500
24002500240025002400250024013d001e00050006000a0006000c000a000c000a000600
0a0006010a0006010a0006010a0006000a0006020a0006000a0006003c0024015b000207
01010001020b06000a0006000a0006010a0006000a0006000a0006000a00060009000600
0c000a000c000a000c000a0006010a0006000a000c000a002a0025002a00240125003600
5c0057002a0024002a0024002a0025002a0025002a005d000f000a0006000c000a000601
0a000c0006000c000a000c000600090006000c000a000c0006000c000600090006000900
06000c00060009003700290024005e000209000002020100021006000a0006000a000601
0a0006000a0006000a0006000a000600090006000c000a000c000a000c000a0006010a00
06000a000c000a002a0025002a002401250036005c0057002a0024002a0024002a002500
2a0025002a005d000f000a0006000c000a0006010a000c0006000c000a000c0006000900
06000c000a000c0006000c00060009000600090006000c00060009003700290024005e00
020701010001020b06000c000a000c000a000c000600090006000c000600090006000a00
06000a0006000a0006010a000c000a000c0004000c000a0006013700240025002a002500
2a0006002b002300240025012400250024022500270006000c000a000601090006010a00
06000a0006000a0006010a0006010a0006000a0006000a0006010a0006000a0006003d00
25002a0039000209000002020100021006000c000a000c000a000c000600090006000c00
0600090006000a0006000a0006000a0006010a000c000a000c0004000c000a0006013700
240025002a0025002a0006002b002300240025012400250024022500270006000c000a00
0601090006010a0006000a0006000a0006010a0006010a0006000a0006000a0006010a00
06000a0006003d0025002a003900020701010001020b06000a0006020a0006010a000600
0a0006000c000600090006000c000600090006030a0020004a0006000900060046002400
250024013700060043005e002a002400290024002a0025002a0025003100090006000a00
060009000601090006000c000a000c0006000c000a000c00060009000600090006000900
06000c000a000c000a000c0006000c0025002401020a000002020100021006000a000602
0a0006010a0006000a0006000c000600090006000c000600090006030a0020004a000600
0900060046002400250024013700060043005e002a002400290024002a0025002a002500
3100090006000a00060009000601090006000c000a000c0006000c000a000c0006000900
060009000600090006000c000a000c000a000c0006000c0025002401020801010001020b
06000c000a000c000a000c000a000c000a000c0006000a0006000a0006000a0006000a00
0600090006000900060009001e000000100006015f0029002400290024003b0044000000
2c002500240125002400250024003d0006010a000c0006010a0006010a0006010a000600
0a0006000a0006010a0006020a0006010a0006000a0006000a00290024002900020a0000
02020100021006000c000a000c000a000c000a000c000a000c0006000a0006000a000600
0a0006000a000600090006000900060009001e000000100006015f002900240029002400
3b00440000002c002500240125002400250024003d0006010a000c0006010a0006010a00
06010a0006000a0006000a0006010a0006020a0006010a0006000a0006000a0029002400
2900020801010001020b06000a0006000a0006020a0006000a000c000a000c0006000900
0600090006010a0006000a0006011e0000013a0060006100240025002400250036004800
000025002a0025002a0025002a002400290006000c000a0006000a000600090006000900
06000c000a000c000600090006000c000600090006000c000a000c000a000c000a000c00
06000c000a000c000600240025002400020a000002020100021006000a0006000a000602
0a0006000a000c000a000c00060009000600090006010a0006000a0006011e0000013a00
60006100240025002400250036004800000025002a0025002a0025002a00240029000600
0c000a0006000a00060009000600090006000c000a000c000600090006000c0006000900
06000c000a000c000a000c000a000c0006000c000a000c00060024002500240002080101
0001020b06000c000a000c000a000c000a000c0006010a0006000a0006010a0006000900
06000c000a000c00060009004d000002620023002a0024002a0025006300070064002401
250024012500240036000a0006000c000600090006010a0006000a0006010a0006010a00
06000a0006000a0006000a0006010a0006000a0006000a0006000a000600290024005100
020a000002020100021006000c000a000c000a000c000a000c0006010a0006000a000601
0a000600090006000c000a000c00060009004d000002620023002a0024002a0025006300
070064002401250024012500240036000a0006000c000600090006010a0006000a000601
0a0006010a0006000a0006000a0006000a0006010a0006000a0006000a0006000a000600
290024005100020801010001020b480006020a0006010a000c000a000c0006000c000a00
0c0006020a0006010a0006011e0000003500240029002400250024002500240006002700
220025002a00240029002400290065000c0006000a0006001b0006000a000c0006000c00
0600090006000c000a000c000600090006000c00060009000600090006000c0006000900
06000c000a000c00480025002a004000020a0000020201000210480006020a0006010a00
0c000a000c0006000c000a000c0006020a0006010a0006011e0000003500240029002400
250024002500240006002700220025002a00240029002400290065000c0006000a000600
1b0006000a000c0006000c000600090006000c000a000c000600090006000c0006000900
0600090006000c000600090006000c000a000c00480025002a004000020801010001020b
36000900060009000600090006000a0006010a0006000a0006000a000c000a000c000a00
0c000a000c000a000c004d000000320025002401290024002a0037000600660047002400
250024002500240136000a0020001e014d000c0006000a0006000a0006000a0006000a00
06000a0006010a0006000a0006020a0006000a0006000a000602480025002400020b0000
02020100021036000900060009000600090006000a0006010a0006000a0006000a000c00
0a000c000a000c000a000c000a000c004d000000320025002401290024002a0037000600
660047002400250024002500240136000a0020001e014d000c0006000a0006000a000600
0a0006000a0006000a0006010a0006000a0006020a0006000a0006000a00060248002500
2400020901010001020b670006000a0006020900060009000600090006000c000a000600
0a0006010a0006030a001e00000040002a00240025002400250024003d000c0068002e00
25002a0024002a002500290025002a003400430000004a000a0006000900060009000600
0c000a000c0006000c000a000c000600090006000c000a000c000a000c00060009000600
0c000a000c00480029002400020b0000020201000210670006000a000602090006000900
0600090006000c000a0006000a0006010a0006030a001e00000040002a00240025002400
250024003d000c0068002e0025002a0024002a002500290025002a003400430000004a00
0a00060009000600090006000c000a000c0006000c000a000c000600090006000c000a00
0c000a000c000600090006000c000a000c00480029002400020901010001020b06000c00
0600090006000a0006020a0006000a0006000c000a000c000a000c000600090006000900
06000c004d0000002c00240025002a002400290024004f000600000030002a0025002400
250024022500240038000000080006000a0006020a0006010a0006000a0006000a000601
0a0006010a0006000a0006010a0006000a0006004c0025002400020b0000020201000210
06000c000600090006000a0006020a0006000a0006000c000a000c000a000c0006000900
0600090006000c004d0000002c00240025002a002400290024004f000600000030002a00
25002400250024022500240038000000080006000a0006020a0006010a0006000a000600
0a0006010a0006010a0006000a0006010a0006000a0006004c0025002400020901010001
020b06000a0006000a000c00060009000600090006000c0006000a0006030a0006000a00
06000a0006000a004a0000002c0025002400250024012900360009000000570024012900
24002a0025002a0025002a005800000005000a000c000a000c000a000c000a000c000600
090006000c000600090006000c000a000c0006000c000600090006000c000a000c000600
690025005500020b000002020100021006000a0006000a000c0006000900060009000600
0c0006000a0006030a0006000a0006000a0006000a004a0000002c002500240025002401
290036000900000057002401290024002a0025002a0025002a005800000005000a000c00
0a000c000a000c000a000c000600090006000c000600090006000c000a000c0006000c00
0600090006000c000a000c000600690025005500020901010001020b0600090006010a00
06000a0006010a000600090006000900060009000600090006000c000a000c000a000c00
200000002400290024002a00250024002500480005000000410024002500240025002400
2500240125006a00000006000a0006010a0006020a0006010a0006000a0006000a000601
0a0006000a0006000a0006000a0006010a00480025005e00020b00000202010002100600
090006010a0006000a0006010a000600090006000900060009000600090006000c000a00
0c000a000c00200000002400290024002a00250024002500480005000000410024002500
2400250024002500240125006a00000006000a0006010a0006020a0006010a0006000a00
06000a0006010a0006000a0006000a0006000a0006010a00480025005e00020901010001
020b0601090006000c000a000c000a000c000a0006010a0006000a0006020a0006010a00
06014a0000002500240025002400290024002a003e001b000000400024002a0024002a00
25002a0025002a00260000001e0006000c000a000c000600090006000900060009000600
0c000a000c0006000c000a000c000a000c000a000c000600090006000c000a000c006b00
2a003900020b00000202010002100601090006000c000a000c000a000c000a0006010a00
06000a0006020a0006010a0006014a0000002500240025002400290024002a003e001b00
0000400024002a0024002a0025002a0025002a00260000001e0006000c000a000c000600
0900060009000600090006000c000a000c0006000c000a000c000a000c000a000c000600
090006000c000a000c006b002a003900020901010001020b06000a0006000a0006030a00
0c000a000c000600090006000900060009000600090006000c000a000c006c0000005500
24002a00250024002500240006000700000041002400250024002500240225006d000000
4a000a0006010a0006000a0006010a0006000a0006010a0006000a0006010a0006010a00
06010a0006010a0048002500020c000002020100021006000a0006000a0006030a000c00
0a000c000600090006000900060009000600090006000c000a000c006c00000055002400
2a00250024002500240006000700000041002400250024002500240225006d0000004a00
0a0006010a0006000a0006010a0006000a0006010a0006000a0006010a0006010a000601
0a0006010a0048002500020a01010001020b06000c000a000c000a000c000a000c000602
0a0006020a0006010a0006000a0006000a000600040000003d00250024012a0025002a00
0600500000002c0025002a0025002a0025002a0025002a006e00000003000c000a000c00
060009000600090006000c0006000c000a000c00060009000600090006000c000a000c00
0600090006000c000a000c0006000c002500020c000002020100021006000c000a000c00
0a000c000a000c0006020a0006020a0006010a0006000a0006000a000600040000003d00
250024012a0025002a000600500000002c0025002a0025002a0025002a0025002a006e00
000003000c000a000c00060009000600090006000c0006000c000a000c00060009000600
090006000c000a000c000600090006000c000a000c0006000c002500020a01010001020b
06000a0006020a0006000a0006000900060009000600090006000c000a000c0006000c00
0600090006000c001b0000006f00240029002500240137000600580000002c0024002500
24022500240025002b000000700006010a0006030a0006000a0006000a0006000a000602
0a0006010a0006010a0006010a0006000a002400020c000002020100021006000a000602
0a0006000a0006000900060009000600090006000c000a000c0006000c00060009000600
0c001b0000006f00240029002500240137000600580000002c0024002500240225002400
25002b000000700006010a0006030a0006000a0006000a0006000a0006020a0006010a00
06010a0006010a0006000a002400020a01010001020a30000c0006000900060009000600
0c000a0006000a0006010a0006000a0006010a0006000a0006010a000600050000005f00
2500240129002400460006004a000000510024002a0025002a0025002a00240158000000
05000a000c000600090006000900060009000600090006000c000a000c00060009000600
0c000a000c000600090006000c000a000c000a000c0006005100020c000002020100020f
30000c00060009000600090006000c000a0006000a0006010a0006000a0006010a000600
0a0006010a000600050000005f002500240129002400460006004a000000510024002a00
25002a0025002a0024015800000005000a000c0006000900060009000600090006000900
06000c000a000c000600090006000c000a000c000600090006000c000a000c000a000c00
06005100020a01010001020a710006000a0006000a0006000a0006000c000a000c000a00
0c0006000900060009000600090006000900060009000600090006000000530024002900
24002500240072000c003a0000002c00730024012500240125002a002700000005000a00
06000a0006000a0006010a0006010a0006010a0006010a0006010a0006010a0006010a00
060109004000020c000002020100020f710006000a0006000a0006000a0006000c000a00
0c000a000c00060009000600090006000900060009000600090006000900060000005300
2400290024002500240072000c003a0000002c00730024012500240125002a0027000000
05000a0006000a0006000a0006010a0006010a0006010a0006010a0006010a0006010a00
06010a00060109004000020a01010001020a740006000c000a000c0006000c000a000603
0a0006030a0006010a0006030a0000000500250024012900240059000600430000002400
29002400290024002a002500240025004a0000000600090006000c0006000c000a000c00
0600090006000c000a000c000600090006000c000a000c000600090006000c000a000c00
060009000601020d000002020100020f740006000c000a000c0006000c000a0006030a00
06030a0006010a0006030a00000005002500240129002400590006004300000024002900
2400290024002a002500240025004a0000000600090006000c0006000c000a000c000600
090006000c000a000c000600090006000c000a000c000600090006000c000a000c000600
09000601020b01010001020a750006000a0006010a000601090006000900060009000600
0900060009000600090006000c000a000c000a000c0006001e0076002500240025002400
290065000c004d000000240025002401250024002900240033002000000006010a000600
0a0006000a0006000a0006000a0006010a0006010a0006010a0006010a0006010a000601
0a000600020d000002020100020f750006000a0006010a00060109000600090006000900
06000900060009000600090006000c000a000c000a000c0006001e007600250024002500
2400290065000c004d000000240025002401250024002900240033002000000006010a00
06000a0006000a0006000a0006000a0006010a0006010a0006010a0006010a0006010a00
06010a000600020b01010001020a770006000c000a000c000600090006000a0006000a00
06010a0006000a0006020a0006000a0006000a0006000a001e000800250024002a002500
2400590006001e0000002a002400290024002a0025002400250065000400000009000600
09000600090006000c000a000c0006000c000a000c000600090006000c000a000c000600
090006000c000a000c000600090006000c000a00020d000002020100020f770006000c00
0a000c000600090006000a0006000a0006010a0006000a0006020a0006000a0006000a00
06000a001e000800250024002a0025002400590006001e0000002a002400290024002a00
2500240025006500040000000900060009000600090006000c000a000c0006000c000a00
0c000600090006000c000a000c000600090006000c000a000c000600090006000c000a00
020b01010001020a6d0006000a0006000a0006010a000c0006000c000a000c0006000900
060009000600090006000c000a000c0006000900060020004a003d002500240129003100
0c00780000002500240025002400250024002a0025003b000500000006000a0006020a00
06010a0006000a0006000a0006010a0006010a0006010a0006010a0006010a000601020d
000002020100020f6d0006000a0006000a0006010a000c0006000c000a000c0006000900
060009000600090006000c000a000c0006000900060020004a003d002500240129003100
0c00780000002500240025002400250024002a0025003b000500000006000a0006020a00
06010a0006000a0006000a0006010a0006010a0006010a0006010a0006010a000601020b
01010001020a770006000c0006000c000a000c0006000a0006000a0006000a0006020a00
06010a0006010a0006010a000800200079002400290024014c000600210000002a002500
2a0024002a00250024014800060000001b000c0006000900060009000600090006000c00
060009000600090006000c000a000c000600090006000c000a000c000600090006000c00
0a000c00020d000002020100020f770006000c0006000c000a000c0006000a0006000a00
06000a0006020a0006010a0006010a0006010a000800200079002400290024014c000600
210000002a0025002a0024002a00250024014800060000001b000c000600090006000900
0600090006000c00060009000600090006000c000a000c000600090006000c000a000c00
0600090006000c000a000c00020b01010001020a3d0006000a0006000a0006000a000600
090006000c000a000c000a000c000a000c000a000c000600090006000c000a000c000600
1a004d0031002500240025002a0031000c00780000002401250024002500240029002400
7a000a00000005000a0006000a0006010a0006000a0006000a0006020a0006010a000601
0a0006010a0006010a0006010a00020d000002020100020f3d0006000a0006000a000600
0a000600090006000c000a000c000a000c000a000c000a000c000600090006000c000a00
0c0006001a004d0031002500240025002a0031000c007800000024012500240025002400
290024007a000a00000005000a0006000a0006010a0006000a0006000a0006020a000601
0a0006010a0006010a0006010a0006010a00020b01010001020a3c000c00060009000600
0c0006000a0006000a0006020a0006010a0006000a0006010a0006010a0006011e005a00
24002900240025004c0006002100000029002400290024002a0025002400250006000500
000006000c000a000c000a000c0006000c000a000c000600090006000900060009000600
0c000a000c000600090006000c000a000c000600090006000c00020d000002020100020f
3c000c000600090006000c0006000a0006000a0006020a0006010a0006000a0006010a00
06010a0006011e005a0024002900240025004c0006002100000029002400290024002a00
25002400250006000500000006000c000a000c000a000c0006000c000a000c0006000900
060009000600090006000c000a000c000600090006000c000a000c000600090006000c00
020b01010001020a5f0006000a0006000a000600090006000c0006000900060009000600
090006000c0006000c000a000c000600090006000c000a000c004d003600250024012900
31000c007800000024002500240025002401290034000c006c001e000a0006030a000600
0a0006000a0006000a0006010a0006000a0006010a0006010a0006010a0006010a000600
020d000002020100020f5f0006000a0006000a000600090006000c000600090006000900
0600090006000c0006000c000a000c000600090006000c000a000c004d00360025002401
290031000c007800000024002500240025002401290034000c006c001e000a0006030a00
06000a0006000a0006000a0006010a0006000a0006010a0006010a0006010a0006010a00
0600020b01010001020a3c000c0006000c000a0006010a0006000a0006000a0006020a00
06000a0006000a0006000a0006000a0006010a004a00050029002400250024004c000600
21000000290024002a00240029002401610006001e00080006000a000c000a000c000a00
0c000600090006000c000600090006000c0006000c000a000c000600090006000c000a00
0c000600090006000c000a00020d000002020100020f3c000c0006000c000a0006010a00
06000a0006000a0006020a0006000a0006000a0006000a0006000a0006010a004a000500
29002400250024004c00060021000000290024002a00240029002401610006001e000800
06000a000c000a000c000a000c000600090006000c000600090006000c0006000c000a00
0c000600090006000c000a000c000600090006000c000a00020b01010001020a5f000600
0a0006000c000a000c000a000c000600090006000900060009000600090006000c000a00
0c0006000c000600090006000c007000030025002a002400290031000c00780000002400
250024002500240025002a005f0005004d000a0006010a0006000a0006000a0006010a00
06000a0006000a0006000a0006000a0006000a0006000a0006010a0006010a000601020d
000002020100020f5f0006000a0006000c000a000c000a000c0006000900060009000600
09000600090006000c000a000c0006000c000600090006000c007000030025002a002400
290031000c00780000002400250024002500240025002a005f0005004d000a0006010a00
06000a0006000a0006010a0006000a0006000a0006000a0006000a0006000a0006000a00
06010a0006010a000601020b01010001020939005a0006000c000a0006010a0006000a00
06020a0006010a0006000a0006010a0006000a0006000a0006000a000600200055002500
240025005f000600210000002a0025002a00240029002400250069007b00050006000900
06000c000a000c0006000c000a000c000600090006000c000a000c000a000c0006000900
06000c000600090006000c000a000c000600090006000400020c000002020100020e3900
5a0006000c000a0006010a0006000a0006020a0006010a0006000a0006010a0006000a00
06000a0006000a000600200055002500240025005f000600210000002a0025002a002400
29002400250069007b0005000600090006000c000a000c0006000c000a000c0006000900
06000c000a000c000a000c000600090006000c000600090006000c000a000c0006000900
06000400020a0101000102095e0036000a000601090006000c0006000c000a000c000a00
0c000a000c0006000c0006000900060009000600090006000c000a000c0006004a003d00
25002a0024006f0006002200000025002400250024012500240005001b0006000a000600
0a0006010a0006000a0006000a0006010a0006010a0006000a0006010a0006000a000600
0a0006010a0006010a000400020c000002020100020e5e0036000a000601090006000c00
06000c000a000c000a000c000a000c0006000c0006000900060009000600090006000c00
0a000c0006004a003d0025002a0024006f00060022000000250024002500240125002400
05001b0006000a0006000a0006010a0006000a0006000a0006010a0006010a0006000a00
06010a0006000a0006000a0006010a0006010a000400020a010100010209510036000c00
0a0006010a0006000a0006000a0006010a0006010a0106010a0006020a0006010a000c00
10007900240025002400590006002100000024002a002400290024002a003c0005000600
0a000c0005000600090006000c000a000c0006000c000a000c000600090006000c000600
0c000a000c000600090006000c000600090006000c000a000c0006005000020c00000202
0100020e510036000c000a0006010a0006000a0006000a0006010a0006010a0106010a00
06020a0006010a000c0010007900240025002400590006002100000024002a0024002900
24002a003c00050006000a000c0005000600090006000c000a000c0006000c000a000c00
0600090006000c0006000c000a000c000600090006000c000600090006000c000a000c00
06005000020a0101000102092400480006000c000a000c000a000c000a000c0006000900
06000c000a000c0006000c000a000c0006000900060009000600090006000a0006000500
7c00240025002a0072000c007d0000002600240025002400250024003e000a0006001c00
4d001b0006010a0006010a0006000a0006000a0006010a0006000a0006000a0006000a00
06010a0006010a0006010a000c001c00020c000002020100020e2400480006000c000a00
0c000a000c000a000c000600090006000c000a000c0006000c000a000c00060009000600
09000600090006000a00060005007c00240025002a0072000c007d000000260024002500
2400250024003e000a0006001c004d001b0006010a0006010a0006000a0006000a000601
0a0006000a0006000a0006000a0006010a0006010a0006010a000c001c00020a01010001
0209250069000a0006010a0006020a0006010a0006010a0006000a0006000a0006000a00
06010a0006000c000a000c000a005d0024012500370006007e0000002c00290024002a00
25003300050020001e00000105000a000c000600090006000c000a000c0006000c000a00
0c000a000c000a000c000600090006000c000a000c000a000c000600090006010a000500
020c000002020100020e250069000a0006010a0006020a0006010a0006010a0006000a00
06000a0006000a0006010a0006000c000a000c000a005d0024012500370006007e000000
2c00290024002a0025003300050020001e00000105000a000c000600090006000c000a00
0c0006000c000a000c000a000c000a000c000600090006000c000a000c000a000c000600
090006010a000500020a010100010209250048000600090006000c000a000c000a000c00
0a000c00060009000600090006000c000a000c0006000c000a000c0006000a0006010a00
0600080025002a00250033000600430000002c002500240025002400360006001b002000
00011b0006000a0006010a0006010a0006000a0006010a0006010a0006010a0006010a00
06000a000601090006000c001a00020c000002020100020e250048000600090006000c00
0a000c000a000c000a000c00060009000600090006000c000a000c0006000c000a000c00
06000a0006010a000600080025002a00250033000600430000002c002500240025002400
360006001b00200000011b0006000a0006010a0006010a0006000a0006010a0006010a00
06010a0006010a0006000a000601090006000c001a00020a010100010209240069000a00
06000a0006000a0006010a0006000a0006010a0006000a0006010a0006000a0006000a00
0c000600090006000c000a001c0024002500240026000600300000002c0025002a002400
290006007f004c003d0040000000050015000c000a000c000600090006000c000a000c00
0a000c000600090006000c000a000c000600090006000c0006000c000a0006010a000600
0500020c000002020100020e240069000a0006000a0006000a0006010a0006000a000601
0a0006000a0006010a0006000a0006000a000c000600090006000c000a001c0024002500
240026000600300000002c0025002a002400290006007f004c003d004000000005001500
0c000a000c000600090006000c000a000c000a000c000600090006000c000a000c000600
090006000c0006000c000a0006010a0006000500020a0101000102082300250048000600
0c00060009000600090006000c0006000c000a000c0006000c000600090006000c000a00
0c0006010a0006010a0006010a00290024002a0025000c00300000005e00240025002400
25002400250024002900400000000a0006000a0006000a0006010a0006030a0006010a00
06010a0006010a0006000a00060009000600090006000a000600020c000002020100020d
23002500480006000c00060009000600090006000c0006000c000a000c0006000c000600
090006000c000a000c0006010a0006010a0006010a00290024002a0025000c0030000000
5e0024002500240025002400250024002900400000000a0006000a0006000a0006010a00
06030a0006010a0006010a0006010a0006000a00060009000600090006000a000600020a
01010001020839002a0036000a0006000a0006020a0006000a0006000a0006000a000600
0a0006000a0006010a000c000a000c000a001c000500090006013d002500240106002700
0000800024002a0025002a00240029002401410081000600090006000c00060009000600
0c000a000c000a000c000a000c000a000c000a000c000600090006000900060009000601
0a0006010c000a00020c000002020100020d39002a0036000a0006000a0006020a000600
0a0006000a0006000a0006000a0006000a0006010a000c000a000c000a001c0005000900
06013d0025002401060027000000800024002a0025002a00240029002401410081000600
090006000c000600090006000c000a000c000a000c000a000c000a000c000a000c000600
0900060009000600090006010a0006010c000a00020a0101000102082c00250036000900
06000c000a000c000a000c000a000c000600090006000c000a000c0006000c000a000c00
0a0006010a000c001b000000040009000600460024002900240063002d00000041002500
2401250024012500240057001e0006010a0006000a0006000a0006000a0006000a000601
0a0006020a0006010a0006020a000c000600090006000a000600020c000002020100020d
2c0025003600090006000c000a000c000a000c000a000c000600090006000c000a000c00
06000c000a000c000a0006010a000c001b00000004000900060046002400290024006300
2d000000410025002401250024012500240057001e0006010a0006000a0006000a000600
0a0006000a0006010a0006020a0006010a0006020a000c000600090006000a000600020a
01010001020825002a0006010a0006010a0006020a0006010a0006010a0006000a000602
090006031e00000028002700230024002500240036003800000039002a0025002a002500
2a0025002a00250082004a0009000600090006000c000a000c000600090006000c000a00
0c0006000900060009000600090006000c000a000c000a0006000a0006010a000c000600
020c000002020100020d25002a0006010a0006010a0006020a0006010a0006010a000600
0a000602090006031e00000028002700230024002500240036003800000039002a002500
2a0025002a0025002a00250082004a0009000600090006000c000a000c00060009000600
0c000a000c0006000900060009000600090006000c000a000c000a0006000a0006010a00
0c000600020a01010001020824002500060009000600090006000c000a000c000a000c00
0a000c00060009000600090006000c000a000c000a000600090006000a00060020000001
30002a0025002a00250036005c000000570024012500240225002a001e00030006000a00
06000a0006010a0006010a0006010a0006010a0006020a0006000a0006000c000a000c00
0a000c0006000a000600020c000002020100020d24002500060009000600090006000c00
0a000c000a000c000a000c00060009000600090006000c000a000c000a00060009000600
0a0006002000000130002a0025002a00250036005c000000570024012500240225002a00
1e00030006000a0006000a0006010a0006010a0006010a0006010a0006020a0006000a00
06000c000a000c000a000c0006000a000600020a01010001020824002a0006010a000600
0a0006010a0006020a0006010a0006000a0006000a0006010a0006000a000c000a000c00
00005e002402250024005a003600000030002a0024002a0025002a00250024003d000000
1100090006000c000600090006000c000a000c000600090006000c000a000c0006000900
0600090006000c0006000a0006030a0006000c000a00020c000002020100020d24002a00
06010a0006000a0006010a0006020a0006010a0006000a0006000a0006010a0006000a00
0c000a000c0000005e002402250024005a003600000030002a0024002a0025002a002500
24003d0000001100090006000c000600090006000c000a000c000600090006000c000a00
0c00060009000600090006000c0006000a0006030a0006000c000a00020a010100010208
250024000600090006000c000600090006000c000a000c000a000c000a000c0006000c00
060009000600090006000c000a0006010a0006004a0035002400290024002a0025006500
190000003500240025002400250024002a0025008300280006000a0006000a0006010a00
06010a0006010a0006010a0006010a0006000a0006000900060009000600090006000900
06000a000600020c000002020100020d250024000600090006000c000600090006000c00
0a000c000a000c000a000c0006000c00060009000600090006000c000a0006010a000600
4a0035002400290024002a0025006500190000003500240025002400250024002a002500
8300280006000a0006000a0006010a0006010a0006010a0006010a0006010a0006000a00
0600090006000900060009000600090006000a000600020a010100010208240029000601
0a0006000a0006000a0006010a0006020a0006000a0006030a0006000c000a000c000600
0900110000002c00250024002500240046000600210124002a0025002a00250024002900
27002000090006000c000a000c000a000c000a000c000600090006000c000a000c000600
090006000c000600090006010a0006000a0006010a0006000c000600020c000002020100
020d2400290006010a0006000a0006000a0006010a0006020a0006000a0006030a000600
0c000a000c0006000900110000002c00250024002500240046000600210124002a002500
2a0025002400290027002000090006000c000a000c000a000c000a000c00060009000600
0c000a000c000600090006000c000600090006010a0006000a0006010a0006000c000600
020a010100010207390024002500060009000600090006000c000600090006000c000a00
0c000a000c000a000c000a000c000a000c000a0006000a0006000a0006010a0004002100
240029002400250034000c00840064002500240325003d002800050006000a0006010a00
06020a0006010a0006010a0006010a0006000a0006000a000c0006000900060009000600
0c000a0006000a00020c000002020100020c390024002500060009000600090006000c00
0600090006000c000a000c000a000c000a000c000a000c000a000c000a0006000a000600
0a0006010a0004002100240029002400250034000c00840064002500240325003d002800
050006000a0006010a0006020a0006010a0006010a0006010a0006000a0006000a000c00
060009000600090006000c000a0006000a00020a01010001020741002400330006010a00
06000a0006000a0006000a0006010a0006020a0006000a000601090006000c0006000c00
0a000c00060009001d00850024002900240025000600270000002a0025002a0025002a00
250083001e000a0006000c000a000c0006000900060009000600090006000c000a000c00
060009000600090006000c000a0006000a0006030a0006000a000c000600020c00000202
0100020c41002400330006010a0006000a0006000a0006000a0006010a0006020a000600
0a000601090006000c0006000c000a000c00060009001d00850024002900240025000600
270000002a0025002a0025002a00250083001e000a0006000c000a000c00060009000600
09000600090006000c000a000c00060009000600090006000c000a0006000a0006030a00
06000a000c000600020a0101000102072c0025003d0006000c0006000c000a000c000600
09000600090006000c000a000c000a000c0006000c000a0006010a0006000a0006000a00
06000a0006000c001e00230024002a0024002f0004000000260024002500240025003300
4d00050006000a0006010a0006010a0006020a0006010a0006010a0006000a0006000c00
06000c000a000c000a000c000a000c0006000a000600020c000002020100020c2c002500
3d0006000c0006000c000a000c00060009000600090006000c000a000c000a000c000600
0c000a0006010a0006000a0006000a0006000a0006000c001e00230024002a0024002f00
040000002600240025002400250033004d00050006000a0006010a0006010a0006020a00
06010a0006010a0006000a0006000c0006000c000a000c000a000c000a000c0006000a00
0600020a01010001020725002400860006000a0106010a0006030a0006010a0006010a00
06000c000a000c000a000c000a000c000600090006010a0006001e004000240025004c00
050000005e0024002a0024002500870020000c000a000c000a000c000600090006000c00
0a000c000a000c000a000c000600090006000c0006000c000a0006000a0006000a000600
0a0006010a0006000c000a00020c000002020100020c25002400860006000a0106010a00
06030a0006010a0006010a0006000c000a000c000a000c000a000c000600090006010a00
06001e004000240025004c00050000005e0024002a0024002500870020000c000a000c00
0a000c000600090006000c000a000c000a000c000a000c000600090006000c0006000c00
0a0006000a0006000a0006000a0006010a0006000c000a00020a01010001020724002500
3d0006000c000600090006000c000a000c000a000c000a000c000a000c00060009000600
0a0006010a0006020a000601090006000c000a000600270023002a003c00050000002300
240025002a00250027000a0006010a0006000a0006010a0006010a0006020a0006010a00
06000a0006000a000c000a000c00060009000600090006000c000a000601020c00000202
0100020c240025003d0006000c000600090006000c000a000c000a000c000a000c000a00
0c000600090006000a0006010a0006020a000601090006000c000a000600270023002a00
3c00050000002300240025002a00250027000a0006010a0006000a0006010a0006010a00
06020a0006010a0006000a0006000a000c000a000c00060009000600090006000c000a00
0601020a01010001020725002a00370006000a0006010a0006000a0006000a0006010a00
06010a0006000c000600090006000c000a000c000a000c000a0006010a00060109000600
770040003d000600000039002a002400250065000c000600090006000c0006000c000a00
0c000600090006000c000a000c000a000c000a000c000a000c000a000c0006000a000600
0a0006030a000601090006001000020b000002020100020c25002a00370006000a000601
0a0006000a0006000a0006010a0006010a0006000c000600090006000c000a000c000a00
0c000a0006010a00060109000600770040003d000600000039002a002400250065000c00
0600090006000c0006000c000a000c000600090006000c000a000c000a000c000a000c00
0a000c000a000c0006000a0006000a0006030a0006010900060010000209010100010207
24002500330006000c000a000c000600090006000c000600090006000c000a000c000600
0a0006000a0006000a0006000a0006010a000c000a000c00060009000601090006003d00
26000c001e002e00250024002a0006000a0006010a0006000a0006000a0006000a000600
0a0006010a0006020a0006020a0006000c0006000c000a000c000a000c000a000c000a00
06000a000700020b000002020100020c24002500330006000c000a000c00060009000600
0c000600090006000c000a000c0006000a0006000a0006000a0006000a0006010a000c00
0a000c00060009000601090006003d0026000c001e002e00250024002a0006000a000601
0a0006000a0006000a0006000a0006000a0006010a0006020a0006020a0006000c000600
0c000a000c000a000c000a000c000a0006000a000700020901010001020639002a002400
370006010a0006000a0006010a0006000a0006000a0006000a000c000a000c0006000900
06000c000600090006030a0006010a0006020c005f0006001d002100240025005f000600
0c000a000c000a000c000a000c000600090006000c000600090006000c000a000c000a00
0c00060009000600090006000a0006000a0006000a0006010a0006010c0006007600020b
000002020100020b39002a002400370006010a0006000a0006010a0006000a0006000a00
06000a000c000a000c000600090006000c000600090006030a0006010a0006020c005f00
06001d002100240025005f0006000c000a000c000a000c000a000c000600090006000c00
0600090006000c000a000c000a000c00060009000600090006000a0006000a0006000a00
06010a0006010c00060076000209010100010206410024002500330006000c000a000c00
060009000600090006000c000a000c0006010a0006000a0006010a0006000a0006000900
0600090006000900060009000600090006000a0006010c004a0000004800690006000a00
06010a0006020a0006010a0006000a0006000a0006010a0006010a0006000a0006010900
06000c000a000c000a000c000600090006000a0006000700020b000002020100020b4100
24002500330006000c000a000c00060009000600090006000c000a000c0006010a000600
0a0006010a0006000a00060009000600090006000900060009000600090006000a000601
0c004a0000004800690006000a0006010a0006020a0006010a0006000a0006000a000601
0a0006010a0006000a000601090006000c000a000c000a000c000600090006000a000600
070002090101000102065e0024002500720006000a0006010a0006020a0006010a000c00
0a000c0006000c000a000c000600090006010a0006000a0006010a001c00060109000600
090006000a000700000011000a000c000600090006000c000a000c000a000c000a000c00
0600090006000c000600090006000c000a000c00060009000600090006010a0006030a00
06000a000600090006001b00020b000002020100020b5e0024002500720006000a000601
0a0006020a0006010a000c000a000c0006000c000a000c000600090006010a0006000a00
06010a001c00060109000600090006000a000700000011000a000c000600090006000c00
0a000c000a000c000a000c000600090006000c000600090006000c000a000c0006000900
0600090006010a0006030a0006000a000600090006001b00020901010001020624002900
24005a0006000c000a000c0006000900060009000600090006010a0006010a0006010a00
0601090006000c000a000c001a00040000007b000a0006010a0006000a000c001b000000
050006000a0006010a0006000a0006010a0006000a0006010a0006000a0006000a000601
0a0006030a000c0006000900060009000600090006000c000a0006011c00020b00000202
0100020b2400290024005a0006000c000a000c0006000900060009000600090006010a00
06010a0006010a000601090006000c000a000c001a00040000007b000a0006010a000600
0a000c001b000000050006000a0006010a0006000a0006010a0006000a0006010a000600
0a0006000a0006010a0006030a000c0006000900060009000600090006000c000a000601
1c000209010100010206250024002500310006000a0006010a0006000a00060209000600
0c000a000c000600090006000c000a0006010a0006030900000088000600090006000c00
0a0006020000700006000c000a000c00060009000600090006000c0006000c000a000c00
0600090006000c000600090006000c000a000c000a000c000a0006000a0006000a000602
0a000601090006001b00020b000002020100020b250024002500310006000a0006010a00
06000a000602090006000c000a000c000600090006000c000a0006010a00060309000000
88000600090006000c000a0006020000700006000c000a000c0006000900060009000600
0c0006000c000a000c000600090006000c000600090006000c000a000c000a000c000a00
06000a0006000a0006020a000601090006001b00020901010001020624002a0025005a00
06000c000a000c00060009000600090006000a0006000a0006010a0006010a0006000c00
0a000c000600090006000900060100007b0006010a0006000c000a0006000a001e000f00
0a0006010a0006030a0006000a0006000a0006000a0006010a0006010a0006000a000600
0a000601090006000c0006000900060009000600090006000a0006001c00020b00000202
0100020b24002a0025005a0006000c000a000c00060009000600090006000a0006000a00
06010a0006010a0006000c000a000c000600090006000900060100007b0006010a000600
0c000a0006000a001e000f000a0006010a0006030a0006000a0006000a0006000a000601
0a0006010a0006000a0006000a000601090006000c000600090006000900060009000600
0a0006001c00020901010001020625002401310006000a0006000a0006021a001e000500
06000c000a000c000600090006000c000a0006010a0006000a0006000a0006000a000000
88000a000c0006000a0006010900060020007b000600090006000c000a000c000a000c00
0a000c000a000c000600090006000c000a000c000a000c000600090006000c0006000900
06010a0006000a0006000a0006020a000c0006000a00020b000002020100020b25002401
310006000a0006000a0006021a001e00050006000c000a000c000600090006000c000a00
06010a0006000a0006000a0006000a00000088000a000c0006000a000601090006002000
7b000600090006000c000a000c000a000c000a000c000a000c000600090006000c000a00
0c000a000c000600090006000c000600090006010a0006000a0006000a0006020a000c00
06000a0002090101000102062400290025005a0006000c0006000c000a000c000a000700
00001b0015000a0006000a0006010a000601090006000c000a000c000600090006000c00
00007b0006000a000c000600090006010a0008001e0006010a0006000a0006000a000601
0a0006000a0006010a0006010a0006000a0006010a0006000a0006000a000c0006000900
06000c00060009000600090006000a0006000c00020b000002020100020b240029002500
5a0006000c0006000c000a000c000a00070000001b0015000a0006000a0006010a000601
090006000c000a000c000600090006000c0000007b0006000a000c000600090006010a00
08001e0006010a0006000a0006000a0006010a0006000a0006010a0006010a0006000a00
06010a0006000a0006000a000c000600090006000c00060009000600090006000a000600
0c000209010100010205390024012500360006000a0006000a0006000a001c0089000000
7b000f000c0006000c000a000c000600700020016c0006010a0006010a00060000008800
06000a0006000a0006000a000c0006001b0000000a000c000600090006000c0006000900
06000c0006000c000a000c000600090006000c0006000c000a000c000a000c0006000900
06000a0006010a0006000a0006000a0006010c000a000600020b000002020100020a3900
24012500360006000a0006000a0006000a001c00890000007b000f000c0006000c000a00
0c000600700020016c0006010a0006010a0006000000880006000a0006000a0006000a00
0c0006001b0000000a000c000600090006000c000600090006000c0006000c000a000c00
0600090006000c0006000c000a000c000a000c000600090006000a0006010a0006000a00
06000a0006010c000a000600020901010001020541002400290024002f00060009000600
0c000a000c0006007000000005000a0006000a0006010a0020001e0006000c0008001e00
0a000c000a000c000600090000007b000600090006000c0006010a000601000005000a00
06010a0006000a0006000a0006000a0006000a0006000a0006000a0006000a0006000a00
06010a0006020c000a000c000600090006000c000600090006000a000601020b00000202
0100020a41002400290024002f000600090006000c000a000c0006007000000005000a00
06000a0006010a0020001e0006000c0008001e000a000c000a000c000600090000007b00
0600090006000c0006010a000601000005000a0006010a0006000a0006000a0006000a00
06000a0006000a0006000a0006000a0006000a0006010a0006020c000a000c0006000900
06000c000600090006000a00060102090101000102052c00250024002500360006010a00
06010a0006000800000005000a000c000600090006001c00000005000a0006008a000000
06020a000601000088000a0006010a00090006000c000a000c004d006c000c000a000c00
0a000c00060009000600090006000c000a000c0006000c000a000c000a000c0006000900
06000c000a000c000a0006000a0006000a0006010a0006000a0006000c000a000c00020b
000002020100020a2c00250024002500360006010a0006010a0006000800000005000a00
0c000600090006001c00000005000a0006008a00000006020a000601000088000a000601
0a00090006000c000a000c004d006c000c000a000c000a000c0006000900060009000600
0c000a000c0006000c000a000c000a000c000600090006000c000a000c000a0006000a00
06000a0006010a0006000a0006000c000a000c00020901010001020525002a0024002900
48000c000a000c000a000c0006000900070000001b0006000a0006010900200000001b00
06000c0011001b000600090006000c000a000c0000007b000600090006020a0006000a00
06002000880006010a0006000a0006010a0006000a0006010a0006000a0006020a000601
0a0006000a0006000a000c000600090006000c000a000c0006000c000a0006010a00020b
000002020100020a25002a002400290048000c000a000c000a000c000600090007000000
1b0006000a0006010900200000001b0006000c0011001b000600090006000c000a000c00
00007b000600090006020a0006000a0006002000880006010a0006000a0006010a000600
0a0006010a0006000a0006020a0006010a0006000a0006000a000c000600090006000c00
0a000c0006000c000a0006010a00020901010001020524002500240136000a0006020a00
060170000000050006000c000a0006018800000005000a0006000a0006010a0006000a00
06000a000000880006000a000c000a000c000600090006000900050000000a000c000600
0c000600090006000c0006000c000a000c000a000c000600090006000900060009000600
0c000a000c0006010a0006010a0006010a0006000a000600090006000c00020b00000202
0100020a24002500240136000a0006020a00060170000000050006000c000a0006018800
000005000a0006000a0006010a0006000a0006000a000000880006000a000c000a000c00
0600090006000900050000000a000c0006000c000600090006000c0006000c000a000c00
0a000c0006000900060009000600090006000c000a000c0006010a0006010a0006010a00
06000a000600090006000c00020901010001020525002a0025002a0044000c000a000c00
0a000c000a000600080000001b0015000a000c000a000c002000000005000a0006000c00
8b000c000600090006000c00060000007b000a0006010a0006000a0006020a0000000500
0a0006000a0006000a0006000a0006000a0006020a0006000a0006010a0006000a000601
0a000c000a000c000a000c00060009000600090006000c000a0006000a000600020b0000
02020100020a25002a0025002a0044000c000a000c000a000c000a000600080000001b00
15000a000c000a000c002000000005000a0006000c008b000c000600090006000c000600
00007b000a0006010a0006000a0006020a00000005000a0006000a0006000a0006000a00
06000a0006020a0006000a0006010a0006000a0006010a000c000a000c000a000c000600
09000600090006000c000a0006000a000600020901010001020524012500240006020a00
060209000700000005000a0006020a00050000006c000c000a00060020000a0006010a00
06000a00000088000600090006000c000a000c000600090006000c004d000f000c000a00
0c000a000c000600090006000c000a000c000a000c0006000c000a000c0006000c000600
090006000a0006010a0006000a0006010a0006000a0006010c0006000900020b00000202
0100020a24012500240006020a00060209000700000005000a0006020a00050000006c00
0c000a00060020000a0006010a0006000a00000088000600090006000c000a000c000600
090006000c004d000f000c000a000c000a000c000600090006000c000a000c000a000c00
06000c000a000c0006000c000600090006000a0006010a0006000a0006010a0006000a00
06010c0006000900020901010001020439002a0025002a0025000c000a000c0006000900
06000a0006001b0000001e0020000c000a000c0006000a0005001e0003001c004a000500
0c000a000c0006001b00200000001e004a0006000a0006010a0006010a00060020001e00
0a0006020a0006010a0006000a0006010a0006000a0006000a0006000a0006000a000c00
0600090006000c0006000c000a000c0006000c000600090006000a000601020b00000202
0100020939002a0025002a0025000c000a000c000600090006000a0006001b0000001e00
20000c000a000c0006000a0005001e0003001c004a0005000c000a000c0006001b002000
00001e004a0006000a0006010a0006010a00060020001e000a0006020a0006010a000600
0a0006010a0006000a0006000a0006000a0006000a000c000600090006000c0006000c00
0a000c0006000c000600090006000a000601020901010001020441002401250024000601
0a0006000a000c0006000a00060005001b0006000a0006000a0006000c000a0006001b00
05000a0106010a000c0006020a000c0006000c000a000c00060009000600090006001b00
1e0006000900060009000600090006000c000a000c000a000c000a000c00060009000600
090006000c0006000a0006010a0006000a0006000a0006000a0006000a0006000a000c00
0a000c00020b0000020201000209410024012500240006010a0006000a000c0006000a00
060005001b0006000a0006000a0006000c000a0006001b0005000a0106010a000c000602
0a000c0006000c000a000c00060009000600090006001b001e0006000900060009000600
090006000c000a000c000a000c000a000c00060009000600090006000c0006000a000601
0a0006000a0006000a0006000a0006000a0006000a000c000a000c000209010100010204
5e0024002900240029000600090006000c0006000a0006000c000a0006020c000a000c00
0a000601090006000a0006000c000a000c0006000a000600090006010a0006000a000600
0a0006010a0006000c0006001e0006000a0006010a0006000a0006030a0006000a000601
0a0006000a0006000a000c000a000c000a000c000a000c00060009000600090006000c00
06000a0006010400020a00000202010002095e0024002900240029000600090006000c00
06000a0006000c000a0006020c000a000c000a000601090006000a0006000c000a000c00
06000a000600090006010a0006000a0006000a0006010a0006000c0006001e0006000a00
06010a0006000a0006030a0006000a0006010a0006000a0006000a000c000a000c000a00
0c000a000c00060009000600090006000c0006000a000601040002080101000102048c00
2500240206010a0006000a000c000a0006010a000c000a000603090006010a000c000600
0a0006000a000600090006000a000c000a000c000a000c0006000c000a000c0006000a00
06000a0020000c000600090006000c0006000c000a000c000a000c0006000c0006000900
06000c000600090006010a0006010a0006010a0006010a0006000a0006000a000c000a00
0c006c00020a00000202010002098c002500240206010a0006000a000c000a0006010a00
0c000a000603090006010a000c0006000a0006000a000600090006000a000c000a000c00
0a000c0006000c000a000c0006000a0006000a0020000c000600090006000c0006000c00
0a000c000a000c0006000c000600090006000c000600090006010a0006010a0006010a00
06010a0006000a0006000a000c000a000c006c00020801010001020425002a0025002a00
25000c000a000c000a000602090006000a0006000a000c000a000c000a0006000a000c00
06000a0006000c000a000c0006000a0006010a0006020a0006000a0006000a000c000a00
0c0006001b0006000a0006000a0006000a0006000a0006000a0006000a0006000a000600
0a0006000a000600090006000c000a000c000600090006000c000a000c0006000c000a00
0c0006000a0006000a000300020a000002020100020925002a0025002a0025000c000a00
0c000a000602090006000a0006000a000c000a000c000a0006000a000c0006000a000600
0c000a000c0006000a0006010a0006020a0006000a0006000a000c000a000c0006001b00
06000a0006000a0006000a0006000a0006000a0006000a0006000a0006000a0006000a00
0600090006000c000a000c000600090006000c000a000c0006000c000a000c0006000a00
06000a0003000208010100010204240125002400250006010a000c000a000c000a000600
0c000a000c0006000a0006000a0006000c0006000a0006000c000a0006010a0006000c00
0a000c0006000900060009000600090006000c0006000a0006000a0006000a000c000600
09000600090006000c000a000c00060009000600090006000c000a000c0006000a000601
0a0006000a0006010a0006010a0006000a0006000a0006000c000a000c001c00020a0000
020201000209240125002400250006010a000c000a000c000a0006000c000a000c000600
0a0006000a0006000c0006000a0006000c000a0006010a0006000c000a000c0006000900
060009000600090006000c0006000a0006000a0006000a000c0006000900060009000600
0c000a000c00060009000600090006000c000a000c0006000a0006010a0006000a000601
0a0006010a0006000a0006000a0006000c000a000c001c00020801010001020425002a00
2400290024000c000a0006020a0006000a0006010a0006000c000a000c000a0006000a00
0c000a000601090006000c000a0006006700480067004c00310067003600480067004801
0c0006000c000a0006000a0006010a0006000a0006010a0006010a0006000a0006010a00
0c000600090006000c0006000c000a000c00060009000600090006000c000a000c000a00
06010a000500020a000002020100020925002a002400290024000c000a0006020a000600
0a0006010a0006000c000a000c000a0006000a000c000a000601090006000c000a000600
6700480067004c003100670036004800670048010c0006000c000a0006000a0006010a00
06000a0006010a0006010a0006000a0006010a000c000600090006000c0006000c000a00
0c00060009000600090006000c000a000c000a0006010a00050002080101000102042400
25002401250006000c000a000c000a000c0006000c000a000c0006000a00060248007f00
36008d00310079003701260025012a0025002a00250029002400290025002a0025002900
2500240025012a0025002a00250029002400290025003300370046003700460037006f00
590079003c0059004c008d0031008d004c008d0036006700480067003600670006000a00
0603090006011a00020a0000020201000209240025002401250006000c000a000c000a00
0c0006000c000a000c0006000a00060248007f0036008d00310079003701260025012a00
25002a00250029002400290025002a00250029002500240025012a0025002a0025002900
2400290025003300370046003700460037006f00590079003c0059004c008d0031008d00
4c008d0036006700480067003600670006000a000603090006011a000208010100010203
23002a0025002a002500330006000a00060044006700480067004c004f00370046003700
3f002500290024002500240029002500240025002a0024002a0024002500240025002401
250024012500240229002401250024002500240125002400250024002500240125002401
250024002a0025002a0025002a0025002a0025002a0025002a0025002a0025002a002500
29000211000002020100020823002a0025002a002500330006000a000600440067004800
67004c004f003700460037003f002500290024002500240029002500240025002a002400
2a0024002500240025002401250024012500240229002401250024002500240125002400
250024002500240125002401250024002a0025002a0025002a0025002a0025002a002500
2a0025002a0025002a0025002900020f0101000102035e0024012500240025003d002900
25002a0025002a0025002a002500240525002a0025002401290024012500240025002a00
24002a0025002a002400290024002a0025002a002500240029002400290024002a002500
2a0024002900240029002400290024002a0025002a002400250024002500240125002400
2500240025002400250024002500240025002401021100000202010002085e0024012500
240025003d00290025002a0025002a0025002a002500240525002a002500240129002401
2500240025002a0024002a0025002a002400290024002a0025002a002500240029002400
290024002a0025002a0024002900240029002400290024002a0025002a00240025002400
25002401250024002500240025002400250024002500240025002401020f010100010203
540025002a002400290024002500240125002400250024012a0025002a00250029002400
290024022900240125002a0025002a002400250024002500240025002401250024012500
2402250024012500240025002401250024022500240025002400290024002a0024002900
2400290024002a0025002a0024002a0025002a0024002a0025002a000211000002020100
0208540025002a002400290024002500240125002400250024012a0025002a0025002900
2400290024022900240125002a0025002a00240025002400250024002500240125002401
25002402250024012500240025002401250024022500240025002400290024002a002400
29002400290024002a0025002a0024002a0025002a0024002a0025002a00020f01010001
02032500240025002401290024002a0025002a0024002a00250024002500240025002401
2500240025002a002500240025002a0024002500240025002400290024002a0025002a00
25002a0025002a0025002a002400290024002a0025002a0024002a002400290024002a00
25002a0025002a0024002900240125002400250024022500240125002400250024012500
24012500021100000202010002082500240025002401290024002a0025002a0024002a00
2500240025002400250024012500240025002a002500240025002a002400250024002500
2400290024002a0025002a0025002a0025002a0025002a002400290024002a0025002a00
24002a002400290024002a0025002a0025002a0024002900240125002400250024022500
24012500240025002401250024012500020f01010001020324002a0025002a0025002401
250024002500240025002a0025002a0024002a0025002a00240029002400250024002a00
2400250024002a0024002a00250024002500240325002402250024002500240025002400
250024002500240025002400250024022500240125002a0025002a002400290024002900
2400290024002a0025002a00240029002400290024002a00021100000202010002082400
2a0025002a0025002401250024002500240025002a0025002a0024002a0025002a002400
29002400250024002a002400250024002a0024002a002500240025002403250024022500
24002500240025002400250024002500240025002400250024022500240125002a002500
2a0024002900240029002400290024002a0025002a00240029002400290024002a00020f
01010001020325002401250024002a0025002a0024002900240125002400250024002500
24002500240125002a002500240025002a0025002400250024012a002400290024002900
24002a0025002a0025002a002400290024002a0025002a0025002a0025002a0024002a00
25002a0025002a0025002a00250024012500240025002401250024002500240125002400
2500240125002c000211000002020100020825002401250024002a0025002a0024002900
24012500240025002400250024002500240125002a002500240025002a00250024002500
24012a00240029002400290024002a0025002a0025002a002400290024002a0025002a00
25002a0025002a0024002a0025002a0025002a0025002a00250024012500240025002401
2500240025002401250024002500240125002c00020f0101000102032400290024002a00
2500240125002401290024002a002400290024002a0025002a0025002a00240125002a00
240025002400290024002900240025002400250024002500240025002400250024002500
240125002401250024022500240025002400250024012500240129002400290024002a00
25002a0024002a00240029002400290024002a0025002a0025002c000211000002020100
02082400290024002a002500240125002401290024002a002400290024002a0025002a00
25002a00240125002a002400250024002900240029002400250024002500240025002400
250024002500240025002401250024012500240225002400250024002500240125002401
29002400290024002a0025002a0024002a00240029002400290024002a0025002a002500
2c00020f010100010203250024002500240025002a0025002a005e0047008e0041002500
2401250024015e008f00210023002401250024002a00250085005e00240057002c002900
85005e002a0025002a0024002a004700900030002a0025002a0025002a00400047003500
910025002a0024002a0025002c0047013000240225002400920093004700230024002500
24012500240025002401940002110000020201000208250024002500240025002a002500
2a005e0047008e00410025002401250024015e008f00210023002401250024002a002500
85005e00240057002c00290085005e002a0025002a0024002a004700900030002a002500
2a0025002a00400047003500910025002a0024002a0025002c0047013000240225002400
920093004700230024002500240125002400250024019400020f01010001020241002400
2a0025002a0024002500240139006400230000002a0025002a0025002a00940000005700
4100000057002a00250024002500240057004b0029000000570034000000340025002400
25002400250000005e002c00250024022500320021003000000024002500240025002a00
5400000091002c0025002a0025002a002500320021003200000039002a0025002a002500
2a002400290024005e0002110000020201000207410024002a0025002a00240025002401
39006400230000002a0025002a0025002a009400000057004100000057002a0025002400
2500240057004b002900000057003400000034002500240025002400250000005e002c00
250024022500320021003000000024002500240025002a005400000091002c0025002a00
25002a002500320021003200000039002a0025002a0025002a002400290024005e00020f
0101000102025e00240025002400250024002a0025002a00230064009500000024012500
2401230096002401230021002400290024002a002500910000005e000000210041002100
24002a002400290024002a00000057003200240029002400290024003900210032002100
24002900240125002c000000570041002400250024012500520021002500230021002401
2500240025002400250024003900021100000202010002075e0024002500240025002400
2a0025002a00230064009500000024012500240123009600240123002100240029002400
2a002500910000005e00000021004100210024002a002400290024002a00000057003200
24002900240029002400390021003200210024002900240125002c000000570041002400
2500240125005200210025002300210024012500240025002400250024003900020f0101
00010202540025002a0024002a00250024002500240039000000430023002a0025002a00
2500240057004300240029005200640025002400250024002a00250000008f0023000000
8f0023002900240025002400250024000000230040002400250024012900320000015100
24012900240025002c0000002300970025002a0025002a002400230021002a0039002100
2400290024002a002400290024002a00230002110000020201000207540025002a002400
2a00250024002500240039000000430023002a0025002a00250024005700430024002900
5200640025002400250024002a00250000008f00230000008f0023002900240025002400
25002400000023004000240025002401290032000001510024012900240025002c000000
2300970025002a0025002a002400230021002a00390021002400290024002a0024002900
24002a002300020f010100010202250024012500240025002a0024002900520021002401
2500240229009100000023005e00640030002a0024002a0025002401470000002c004300
00005500240025002a0024002900240000002c00540025002a0025002401390021013000
2a00250024012900540000005e002c00240225002a00390021005e0064004b0025002400
250024002500240025002400390002110000020201000207250024012500240025002a00
240029005200210024012500240229009100000023005e00640030002a0024002a002500
2401470000002c00430000005500240025002a0024002900240000002c00540025002a00
250024013900210130002a00250024012900540000005e002c00240225002a0039002100
5e0064004b00250024002500240025002400250024003900020f01010001020224002900
24002900240125002401410068002a0025002a0024002900240125005200000190002400
250024002500240029002400410021002400410062002400250024002500240125006401
430024012a0025002a00230047002c0064002c0024002500240151006401680029002400
29002400250052006400980057002a00240029002400290024002a0025002a0039000211
00000202010002072400290024002900240125002401410068002a0025002a0024002900
240125005200000190002400250024002500240029002400410021002400410062002400
250024002500240125006401430024012a0025002a00230047002c0064002c0024002500
24015100640168002900240029002400250052006400980057002a002400290024002900
24002a0025002a003900020f010100010202240025002401290024002900240029002401
250024012500240025002400290024002900240025002a00240029002402250024012500
24002a0025002a0024002900240029002401250024002900240025002400250024012500
24002500240029002400250024012a0024002500240125002a00250024002a0024002500
240125002400250024012500021200000202010002072400250024012900240029002400
29002401250024012500240025002400290024002900240025002a002400290024022500
2401250024002a0025002a00240029002400290024012500240029002400250024002500
2401250024002500240029002400250024012a0024002500240125002a00250024002a00
24002500240125002400250024012500021001010001020225002a002500240025002401
2500240025002a00240029002400290024002a0025002402250024002500240129002400
290024002a0025002a0025002401250024012500240129002401250024002a0025002a00
2400290024002a002500240125002a002400250124002a0025002a002400250024012500
240029002400290024002a002400290024002a000212000002020100020725002a002500
2400250024012500240025002a00240029002400290024002a0025002402250024002500
240129002400290024002a0025002a002500240125002401250024012900240125002400
2a0025002a002400290024002a002500240125002a002400250124002a0025002a002400
250024012500240029002400290024002a002400290024002a0002100101000102012300
24012a0025002a0025002a00240029002400250024002500240125002401290024002900
24002a0025002a002500240225002401250024002900240029002400290024002a002500
2400290024002a002500240125002401250024002a0025002a00240025002a0024002a00
250024002500240025002a00240029002400250024022500240025002400250024000212
0000020201000206230024012a0025002a0025002a002400290024002500240025002401
2500240129002400290024002a0025002a00250024022500240125002400290024002900
2400290024002a0025002400290024002a002500240125002401250024002a0025002a00
240025002a0024002a00250024002500240025002a002400290024002500240225002400
250024002500240002100101000102024001410080004000950040019500400080004100
80005100540051002c0094002c005100540051002c015100540051002c0094002c002500
2a0024022500240225002401250024002500240025002a0025002a0025002a0025002400
2500240025002400250024002500240025002a00240029002401250024002a0024002900
2400290024002a0024002900240029000212000002020100020740014100800040009500
4001950040008000410080005100540051002c0094002c005100540051002c0151005400
51002c0094002c0025002a0024022500240225002401250024002500240025002a002500
2a0025002a00250024002500240025002400250024002500240025002a00240029002401
250024002a00240029002400290024002a00240029002400290002100101000102243900
410092002a0025002a0025002a0024002a0024002900240225002401290024002a002500
2a00240029002400290024012500240125002a0024002500240025002400250024002500
2400250024012500021200000202010002293900410092002a0025002a0025002a002400
2a0024002900240225002401290024002a0025002a002400290024002900240125002401
25002a00240025002400250024002500240025002400250024012500021001010001022c
390040002c00240025002a0025002a002500240125002401250024012500240029002400
290024002900240025002a0025002a002400290024002a00240029002400290024002a00
02120000020201000231390040002c00240025002a0025002a0025002401250024012500
24012500240029002400290024002900240025002a0025002a002400290024002a002400
29002400290024002a000210010100010234390040002c00290024002900240029002400
2a0024012500240225002402250024012500240025002402250024000212000002020100
0239390040002c002900240029002400290024002a002401250024022500240225002401
250024002500240225002400021001010001023c39005e00940024002a0025002a002500
2a0025002a0025002a0025002a002400290024002a0025002a0025002a00021200000202
0100024139005e00940024002a0025002a0025002a0025002a0025002a0025002a002400
290024002a0025002a0025002a0002100101000102444000910094002401250024002500
240125002400250024002500021200000202010002494000910094002401250024002500
240125002400250024002500021001010001024b390040005e002a0024002a0025002a00
02120000020201000250390040005e002a0024002a0025002a0002100101000102660000
020201000269010100010266000002020100026901010001026600000103026901010001
01d7000001d8
%%EndData
end
%%PageTrailer
%%Trailer
%%BoundingBox: 0 0 217 157
%%EOF
Deleted tip/41example.png.

cannot compute difference between binary files

Deleted tip/41example.txt.
1
2
3
4
5
6
7
8
9
10










-
-
-
-
-
-
-
-
-
-
+----------++----------+
|          ||          |
| Widget#1 ++ Widget#2 |
|          ++          |
|          ||          |
|          ||          |
|          ||          |
|          ||          |
|          ||          |
+----------++----------+
Deleted tip/42.tip.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84




















































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TIP:		42
Title:          Add New Standard Tk Option: -clientdata
Version:	$Revision: 1.1 $
Author:         Bryan Oakley <[email protected]>
State:		Draft
Type:           Project
Vote:		Pending
Created:	05-Jul-2001
Post-History:	
Tcl-Version:    8.4

~ Abstract

This TIP proposes to add a new standard option, -clientdata, for all
Tk widgets.

~ Rationale

Many modern and not so modern widget toolkits provide a way to attach
programmer defined data to a widget.  Tk lacks such a feature.  The
only way to accomplish a similar feat today is by storing data in a
global or namespace variable keyed by widget name.  This doesn't lend
itself very well to general purpose library routines.

One example of how this could be used is in prototyping additional
widget functionality.  For example, [39] requests a new option for
each widget that enables a widget to declare that it is part of a
larger compound widget.  One potential use of this new flag is in the
Tk library code that handles keyboard traversal.

With the option proposed in this TIP, it would have been quite simple
to prototype the necessary changes at the script level, making it
easier to validate the utility of the requested change in TIP #39, and
to provide a reference implementation of the affected library
procedures.

Another example use of this flag would be in the development of a
graphical interface builder such as SpecTcl or Visual Tcl.  With
applications that let you create widgets interactively, it is often
convenient to attach metadata directly to the widget.  For example,
the tool might allow a user to enter comments about a given widget;
or, perhaps the tool provides a way to clone a widget and wants to
maintain the relationship by storing the name of the original widget.
It seems to make sense to keep this information with the actual widget
rather than in a global array.

A third example is that a widget or dialog could use this field to
store history information.  For example, a file selection dialog could
remember the last directory it visited.  An entry widget could
remember previous values for some sort of undo functionality.
Individual widgets could keep their default and most recent values to
support "revert" or "default" buttons in a form.

... and the list goes on.  The bottom line is, it adds flexibility
that can be leveraged in many ways.  Impact on the core is minimal
since it merely requires the storage and retrieval of information.
And the mechanism is already in place; we merely need to define a slot
in the widget data structure to store the information.

~ Specification

Suggested wording for the ''options'' man page (which, I suspect, can
be greatly improved upon):

| Command-Line Name: -clientdata
| Database Name: clientData
| Database Class: ClientData

 > ''Specifies programmer defined data to be associated with the
   widget.  The Tk libraries do not use this information or require
   the information to be in any particular format.  It is purely for
   use by the application.''

~ Lame Joke

Did you hear the one about the three legged dog that went into a
saloon, jumped up on the nearest stool, banged his good foot on the
bar, and with a steely-eyed glare said "I'm lookin' for the man that
shot my Paw!"?

~ Copyright

This document has been placed in the public domain accompanied with
only a small and very personal amount of fanfare.
Deleted tip/43.tip.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
















































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TIP:            43
Title:          How to be a TIP Editor
Version:        $Revision: 1.3 $
Author:         Donal K. Fellows <[email protected]>
State:          Draft
Type:           Informative
Vote:           Pending
Created:        07-Jul-2001
Post-History:   

~ Abstract

This TIP describes some of the rules and guidelines that the TIP
Editor uses when accepting TIPs for the first time.

~ Rules

There are some things that are hard rules, which should be obeyed even
if it means having to postpone acceptance of the TIP or rewrite it
yourself.

 * ''Every TIP ''must'' be relevant to Tcl and/or Tk.''

 > It's probably better to suggest that changes that affect just a
   single extension should be dealt with through the processes for
   feature requests for that extension, but where they are about
   providing some kind common interface across a whole group of
   extensions, it is fair to think of using a TIP as well.  I'd reckon
   that's up to the discretion of the editor, but no TIP should be
   rejected by the editor out of hand, and never without a proper
   written explanation.

 > Of course, ultimately whether a TIP is relevant to Tcl and/or Tk is
   up to the whole Tcl Core Team (as described in [0]) so you should
   try to ensure that their policy on TIP-suitability is what you are
   enforcing.

 * ''Every TIP ''must'' be in the TIP format (see [3] for details.)''

 > This is important because it allows the TIP rendering engine to
   handle all the formatting and indexing automatically for you.  Note
   that it is very picky about the format of the header, and not that
   choosy about the format of the content (though it is not a good
   idea to have a sub-item of a list without a previous main item.)
   Get it wrong, and the TIP archive engine will fail in all sorts of
   "interesting" ways.  Take particular note of the format of the
   ''Created:'' line, as it surprises many people in just how exact it
   must be.

 * ''Every author ''must'' be associated with a real email address.''

 > You should fill this in yourself if it is not already supplied and
   spam-protected addresses are not acceptable, since they tend to
   frustrate the main purpose of TIPs which is to foster collaboration
   on things to improve Tcl and Tk.  Proper email addresses help this
   by always allowing people to contact the author of the TIP to give
   suggestions to improve the TIP or to resolve issues they have with
   it.

 * ''Every TIP ''must'' have an Abstract.''

 > Not everyone has the desire, or the time, to read each TIP.
   Providing an abstract allows people to determine whether the TIP is
   relevant to what they are looking for at the moment.  Searches on
   the TIP archive also always search the abstract.

 > Abstracts should be formed of the section title whose text is
   precisely "Abstract" and then a single normal paragraph of no more
   than around 200 words; if it is longer than that then it is no
   longer a summary or abstract but a genuine major part of the
   document body.  While authors should write their own abstracts, it
   is reasonable for the editor to add one, particularly if the
   author's native language is not English.

 * ''Every TIP ''must'' have a Copyright declaration.''

 > World-wide copyright laws are funny things, and I'm not sure that
   it is safe to assume that the submission of the TIP constitutes
   permission for all the things that might be done with it in the
   future.  Work around this by getting every author to clarify the
   copyright position at time of submission by explicitly saying that
   the document is placed in the public domain.  (The way that TIPs
   are kept under CVS should assuage most concerns relating to
   misrepresentation through inappropriate modifications, and it is a
   definite aim that TIPs should be distributed as widely as possible
   to encourage a wide dissemination of the ideas contained.)

~ Guidelines

 * TIPs should be written in English (unless there are very good
   reasons otherwise) since that is the language most widely
   understood in the Tcl/Tk community.

 * TIP should be written so as to be readable!  This requirement is
   not strict, but it will make it much easier for the TCT to
   evaluate...

 * The Abstract should be written in a third-person voice, and
   ''definitely'' in English.  It isn't so important for the rest of
   the TIP, but the abstract will be seen quite a bit more widely and
   without as much context.  It also fits in with the style of the
   existing abstracts.

 * The section headings and title should be capitalised according to
   the rules for such things in English.  It looks neater that way.

 * Spell check before checking in.  No sense in having glaring errors
   in the initial version!  (I do not enforce the use of either US or
   UK spellings; that is rightfully the domain of the TIP author who
   might be based anywhere in the world.)  Be especially careful with
   the checking of the spellings of the names of file names, C
   identifiers or Tcl commands/variables/etc.

 * C identifiers and Tcl commands/variables/etc. should normally be
   ''emphasized'', as should file names.  This should be moderated by
   good sense though; the aim of such emphasis is to indicate that it
   is a reference to an entity in the code domain as opposed to the
   domain of the English language.

 * TIP numbers should be allocated by the TIP editor in sequence of
   the order they are checked into the CVS archive.  Make sure that
   the filename (''num.tip'') matches up with the ''TIP: num'' header
   or bizarre things may happen.

 * Where someone submits a TIP proposing a new Tk widget, invite them
   to supply an image (or two) of how the widget will look in
   operation.  These images will need to be checked in by hand, and
   will not be editable.  Images should be checked in in both a raster
   form (GIF, JPEG or PNG) and as Encapsulated PostScript (EPS) - make
   sure that you set the binary flag on the file when you do this.
   Where someone produces a diagram with a tool that can produce FIG
   files, it is nice if you can check that into CVS as well so that
   the diagram itself can be maintained if necessary.

 > As a convention, name the images with the TIP number as the first
   part of the name.  This makes it much easier to determine what TIP
   a particular image is associated with (and certainly beats grepping
   the whole set of TIPs!)

 * Once a TIP is checked in, it should normally be published to
   news:comp.lang.tcl, news:comp.lang.tcl.annouce and the tcl-core
   mailing list (though with some TIPs it is obvious that wider
   dissemination is less useful.)  It is a good idea to send a copy to
   the TIP author as well, as this lets them know not only that the
   TIP has been accepted but also what it looks like and that it has
   been distributed to the wider community.  The ''postnews.tcl''
   script that comes with the TIP renderer distribution is designed to
   do all this with a minimum of fuss.  A quick "Thank You" note is
   also courteous.

 * When a TIP has been accepted by the TCT in a TYANNOTT vote, put a
   note into the log to record what the vote was.  It is best to do
   this as part of the log message for when you change the Vote: and
   Status: headers...

''I need to write something here about the production of PS and PDF
versions of the whole TIP archive, but that side of the code is not
yet finished and released.''

~ Notes

TIPs do not need to be tightly focussed.  Making them so does make
them easier to evaluate, but it might also remove the real rationale
behind the changes.  Instead, it is best that they form a coherent
logical entity, since I believe that it is that which makes for a good
TIP.

The title, section headings and list item headings must be plain text.
This is because there are output formats which are very picky about
what is allowed in those sorts of places (PDF bookmarks have
especially strict restrictions) and plain text has the virtue of being
accepted pretty much everywhere.

~ Copyright

This document is placed in the public domain.
Deleted tip/44.tip.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
























































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TIP:            44
Title:          Move Tk's Private Commands and Variables into ::tk Namespace
Version:        $Revision: 1.8 $
Author:         Don Porter <[email protected]>
State:          Final
Type:           Project
Vote:           Done
Created:        16-Jul-2001
Post-History:   
Tcl-Version:    8.4

~ Abstract

This TIP proposes that Tk's private commands and variables be moved
into the namespace ''::tk'' or its descendent namespace(s).

~ Background

Tk defines several commands and variables in the global namespace
that are not intended for public use.  Some of the commands are
used for widget bindings.  Some of the variables are used to maintain
widget state information.  The definition of these "private" commands
and variables in the global namespace is a legacy held over from Tk 4
and the pre-8 versions of Tcl in which there was only one namespace.

Fortunately, the coders of Tk have maintained good discipline in
naming these commands and variables intended for Tk's internal
use only.  The commands and variables matching the glob pattern
''::tk[[A-Z]]*'' are private.  Consider this interactive tktest session
with Tk 8.3.3:

| $ cd tk/unix
| $ make runtest
| ...
| % # Put Tk through its paces to define all commands and variables
| % source ./../tests/all.tcl
| ...
| % llength [info commands {tk[A-Z]*}]
| 183
| % llength [info vars {tk[A-Z]*}]
| 5

So, on Unix, there are 183 private commands and 5 private variables
polluting the global namespace.  The number and list of commands
and variables varies a bit from platform to platform due to
differences in widget bindings.

More recently, private commands in Tk have been added in the ''::tk''
namespace; two examples are ''tk::PlaceWindow'' and ''tk::SetFocusGrab''.
Likewise the private variable ''tk::FocusGrab'' has also been added
in the ''::tk'' namespace.

There are three reasons why it is better for Tk's private commands
and variables to be moved out of the global namespace and into the
''::tk'' namespace.

 1. The large number of commands and variable makes it more difficult
    to use interactive ''[[info commands]]'' and ''[[info vars]]'' or
    ''[[info globals]]'' introspection to learn about what application
    specific commands and variables are defined.

 2. Placing private commands and variables in the global namespace
    gives them a higher profile, and increases the likelihood that
    they will be used publicly, against the intent of Tk's interface.

 3. By making more use of its own namespace for keeping track of its
    own internals, Tk becomes a better example for authors of other
    packages to copy.

~ Proposal

All commands and variables created by Tk and matching the glob pattern
''::tk[[A-Z]]*'' shall be renamed to a name contained within the
''::tk'' namespace or one of the descendent namespaces of ''::tk''.

The global variable ''::histNum'' created by ''tk/library/console.tcl''
shall also be renamed to ''::tk::HistNum''.

All commands and variables created by the proposal will be given names
that begin with an uppercase character (''[[A-Z]]'') to indicate their
internal status according to the conventions of the Tcl Style Guide
(http://purl.org/tcl/home/doc/styleGuide.pdf).

~ Compatibility and Migration

This proposal only deals with the internals of Tk, so technically there
are no compatibility issues, because Tk users should not be depending
on these private commands and variables.

That said, because these commands and variables have had a high
profile in the global namespace, it seems likely that some users
have written code that depends on them.  To aid such users in a
migration away from that dependence, it is also proposed that
Tk provide two additional unsupported commands:

| ::tk::unsupported::ExposePrivateCommand commandName

and

| ::tk::unsupported::ExposePrivateVariable variableName

The command ''[[::tk::unsupported::ExposePrivateCommand commandName]]''
restores the existence of the Tk private command ''commandName'' in
the global namespace as it was before adoption of this proposal.
The command ''[[::tk::unsupported::ExposePrivateVariable variableName]]''
restores the existence of the Tk private variable ''variableName'' in
the global namespace as it was before adoption of this proposal.
For example, a Tk user who had written code that made use of the Tk
private command ''tkCancelRepeat'' can add the following code to
continue working with Tk after acceptance of this proposal:

| if {![llength [info commands tkCancelRepeat]]} {
|     tk::unsupported::ExposePrivateCommand tkCancelRepeat
| }

These migration commands are in the namespace ''tk::unsupported'',
a new namespace to be used for unsupported commands in Tk.  This
namespace may and should be used for any other unsupported commands
to be created in Tk.  Their implementation is in the new file
''tk/library/unsupported.tcl''.

~ Reference Implementation

This proposal has already been implemented and committed to Tk's
CVS repository on the branch tagged ''dgp-privates-into-namespace''.
That branch is up to date with Tk's HEAD branch as of July 16, 2001.

To make an anonymous checkout of the reference implementation into
a directory named ''tkprivate'', run the following CVS commands:

| $ cvs -d :pserver:[email protected]:/cvsroot/tktoolkit \
|   login
| (Logging in to [email protected])
| CVS password: <Enter>
| $ cvs -z3 -d :pserver:[email protected]:/cvsroot/tktoolkit \
|   co -r dgp-privates-into-namespace -d tkprivate tk

The reference implementation has the same results on the Tk
test suite as the HEAD revision.

In the tktest of the reference implementation:

| $ make runtest
| ...
| % source ./../tests/all.tcl
| ...
| % llength [info commands {tk[A-Z]*}]
| 0
| % llength [info vars {tk[A-Z]*}]
| 0

~ See Also

Feature Request 220936:
http://sf.net/tracker/?func=detail&aid=220936&group_id=12997&atid=362997

~ Related Ideas / Future Work

The ideas in this section are ''not'' part of this proposal.  They are
related ideas mentioned here as explicitly outside the scope of this
proposal so they will not be counter-proposed.

 * ''Shouldn't Tk's public commands and variables be moved to ::tk too?''

 > Well, yes, I think they should, but that change clearly involves 
   sorting out more difficult compatibility/migration issues.  The
   current proposal is limited to the less controversial topic of
   Tk's private commands and variables.  We'll tackle the rest later.

 * ''Shouldn't Tk make use of [[namespace code]] in its bindings?''

 * ''Wouldn't it make Tk better organized if commands like
   [[tk::IconList_Add]] were further renamed [[tk::IconList::Add]]?''

 > Perhaps so.  There may be many ways in which Tk can and should 
   make better or more idiomatic use of namespaces.  That's not the
   point of this proposal, though.  The point is to get these commands
   and variables out of the global namespace.  Once that is accomplished,
   then these other matters are unquestionably internal and can proceed
   at the discretion of the maintainers without further TIP review.

~ Copyright

This document has been placed in the public domain.
Deleted tip/45.tip.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90


























































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TIP:            45
Title:          Empty index lists for [lindex] and [lset]
Version:        $Revision: 1.8 $
Author:         Kevin Kenny <[email protected]>
Author:         Don Porter <[email protected]>
State:          Accepted
Type:           Project
Vote:           Done
Created:        18-Jul-2001
Post-History:   
Discussions-To: news:comp.lang.tcl,mailto:[email protected]
Keywords:       lindex,lset,multiple arguments,sublists
Tcl-Version:    8.4b1

~ Abstract

TIP's #22 and #33 contain an oversight in specifying the behavior
of the multi-argument forms of ''lset'' and ''lindex'' when an empty
index list is specified.  The intended behavior is that an empty list
of indices designates the entire list.

~ Rationale

In the discussion of [33]
([http://www.geocrawler.com/archives/3/7375/2001/5/0/5784409/]), Jim
Ingham pointed out that the list of indices presented to the
multi-argument forms of ''lindex'' and ''lset'' is analogous to a
database cursor.  This cursor is conceptually navigating a tree
structure; the command:

|  lindex $list {1 2 3}

means, "extract the sublist at index 1 in $list, the sublist at
index 2 in that list, and the element at index 3 in that list".

When implementing this functionality, the author of this TIP
realized that [22] and [33] provide no way to
address the root of the tree -- the entire list being manipulated.
An empty list of indices is a convenient means of specifying the root.

~ Specification

 1. The specification of ''lindex'' in [22] shall be amended so that
    the forms:

|  lindex list

 >  and

|  lindex list {}

 >  will return the value of the entire list.  The ''list'' parameter
    is not required to be a well-formed Tcl list when
    this form is used.

 1. The specification of ''lset'' in [33] shall be amended so that
    the forms:

|  lset var value

 >  and

|  lset var {} value

 >  will simply store the supplied value into the variable named ''var''.
    Neither the old nor the new value of ''var'' is required to be
    a well-formed Tcl list when this form is used.  The return value of
    the operation, as with all other uses of ''lset'', is the
    new value of ''var''.

~ Reference implementation

Work progresses on implementing this functionality; the currently
committed version is on SourceForge in the branch labeled,
''kennykb-tcl-22-33''.

~ Discussion

Since this proposed change introduces syntax that is expressly forbidden in
[22] and [33], it does not have any impact on backward compatibility.
For the same reason, the author thought it unwise to proceed with its
implementation without a vote of the TCT.

~ See Also

[22], [33].

~ Copyright

This document has been placed in the public domain.
Deleted tip/46.tip.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59



























































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TIP:		46
Title:          Consistent Overlap Behavior of Area-Defining Canvas Items 
Version:        $Revision: 1.2 $
Author:         Gerhard Hintermayer <[email protected]>
State:          Draft
Type:           Project
Vote:           Pending
Created:        18-Jul-2001
Post-History:   
Tcl-Version:	8.4

~ Abstract

This document proposes that all canvas items that define an area
should behave the same in terms of interior points, i.e. points that
return the enclosing object id when submitted to
''[$canvas find overlapping]''.  Currently polygons behave differently
from the rest (rectangle, arc, oval).

~ Rationale

As long as these area-defining canvas items are filled, there's no problem.
The interior points belong to the object. But when the object is not filled
(i.e. -fill "" is used), only polygons consider inside points as overlapping.
For the rest of the area-defining canvas items, an interior point is ''not''
considered to overlap the object.  This makes it impossible to

   * define invisible or not filled mouse sensitive areas other than polygons
     because moving the pointer inside of an arc/oval/rectangle creates both
     an ''<Enter>'' and a ''<Leave>'' event, even though the pointer is still
     inside the item.

   * do object-oriented selection on a canvas. Consider you want to select
     a (not filled) oval, you ''have to'' click on the vertice, or else you
     won't find a overlapping item.

Well, I see the point, that this proposal might break existing code, but
from the number of replies to my postings at news:comp.lang.tcl ,
''[$canvas find overlapping]'' is not used very often.

One possibility to fix the backward compatibility is to introduce 2
different fill colors for the 2 cases - object either hollow or solid
but not filled. Then inside points would not overlap hollow objects, but
would overlap solid objects.

~ Proposal

We should either choose a wire frame model or an object-oriented model
for canvas objects. To my mind an object-oriented approach is better.
Right now we have a mixture of both. Polygons are objects, arcs, ovals and
rectangles are wire frames.

What I'd like is: all points which are inside of an area object should return
the enclosing object when passed to find overlap, ''regardless'' of the fill
color of the item.

~ Copyright

This document has been placed in the public domain.
Deleted tip/47.tip.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189





























































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TIP:            47
Title:          Modifying Tk to Allow Writing X Window managers
Version:        $Revision: 1.4 $
Author:         Neil McKay <[email protected]>
Author:         Andreas Kupries <[email protected]>
State:          Draft
Type:           Project
Vote:           Pending
Created:        19-Jul-2001
Post-History:   
Tcl-Version:    8.4

~ Abstract

With a few modifications to the Tk core, extensions could be
written that would allow X window managers to be implemented
as Tcl/Tk scripts.

~ Requirements

Writing X window managers in Tk requires some facilities that
the current Tk core doesn't provide. A window manager
must be able to:

 * draw to, and handle events on, the display's
	root window (including ''<Create>'',
	''<MapRequest>'', ''<ResizeRequest>'', ''<CirculateRequest>'',
	and ''<ConfigureRequest>'' events, which are currently
	ignored)

 * embed arbitrary windows inside Tk windows

 * receive ''<PropertyNotify>'' events from embedded windows

 * perform a variety of other X-specific operations

Window embedding can be handled by an extension, if it is not
incorporated into the Tk frame widget at some later time.
Likewise, the X-specific operations can be handled by
an extension. However, Tk as it currently stands cannot
access the display's root window, nor can ''<PropertyNotify>''
events be received from embedded windows; doing these
things requires core modifications.

~ Root Window Access

The root window is special in many ways:

 * It does not need to be created

 * It cannot be destroyed, moved, or resized

 * Only one process can receive ''<ButtonPress>'' and ''<ButtonRelease>''
	events from it, and only one process can have the
	''SubstructureRedirect'' and ''ResizeRedirect'' masks set

 * It has no physical parent window

Because of these properties, access to the root window via a Tk
widget presents some difficulties. First, the widget's window cannot
be created in the standard way; however, this problem may be solved by
providing a non-standard creation routine via the
''Tk_SetClassProcs'' procedure described in [5].
Likewise, the event handling required by the root window
can be enabled in an extension, although some care is required
when enabling ''<ButtonPress>'' and certain other events.
What really causes problems is the lack of a physical parent.
There are many places in Tk where it is assumed that only
toplevel widgets have no physical parent within the application;
this is reflected in the Tk source by the use of the ''TK_TOP_LEVEL'' flag.
This flag is used to mean different things in different places.
In particular, the ''TK_TOP_LEVEL'' flag may mean:

 * This window is a toplevel widget

 * This widget has a wrapper window

 * This widget's window is controlled by the window manager

 * This window is at the top of a physical window hierarchy
	within the current application

In the current version of Tk, toplevel widgets have all of these
properties, and no other widgets have any of these properties;
hence a single flag suffices.
If we create a widget whose window is the display's root, then this
is no longer the case; a root window has the last property, but not
the first three. For this reason, it is necessary to replace
the ''TK_TOP_LEVEL'' flag with at least two distinct flags. A better
idea is to replace the ''TK_TOP_LEVEL'' flag with four flags, one for each
of the properties listed above. (Even in a standard Tk distribution,
this replacement is desirable for documentation reasons, since it will
indicate what property of a toplevel widget is important in the current
circumstances.) We must also replace the ''Tk_IsTopLevel'' macro with
several macros, or just eliminate it entirely.

One possible set of flag names is:

 TK_TOP_LEVEL: this is a toplevel widget

 TK_HAS_WRAPPER: this window has a wrapper window

 TK_WIN_MANAGED: this window is controlled by the window manager

 TK_TOP_HIERARCHY: this window is at the top of a physical window hierarchy

~ New Event Bindings and Substitutions

A window manager must be able to intercept certain events on the root
window that the standard Tk distribution doesn't recognize, and
it must be able to obtain information about those events. In particular,
it needs to respond to ''<CirculateRequest>'', ''<ConfigureRequest>'',
''<CreateNotify>'', ''<MapRequest>'', and ''<ResizeRequest>'' events.
These events are ignored by standard Tk, and need not be enabled by
default; however, they need to be included in the list of events recognized
by the Tk ''[bind]'' command. Adding this facility is very simple.

Obtaining information about these events is also necessary.
This is usually done via %-substitutions in the ''[bind]'' command;
however, there are two pieces of information that are necessary
for implementing a window manager that cannot be obtained via
the current %-substitution mechanism: the numerical X window ID,
required to handle ''<CreateNotify>'' events, and the property name,
for handling ''<PropertyNotify>'' events. This information could be
obtained by adding two new %-substitutions:

 %i: substitute the numerical window ID for the event

 %P: substitute the atom name for the property being changed

~ Propagating <PropertyNotify> Events

In order to receive ''<PropertyNotify>'' events from embedded windows,
the Tk event loop must handle events not just for windows that
are represented by ''Tk_Window'' structures, but also for their children.
One way to accomplish this is to add another flag for the
''Tk_Window'' struct, and alter the event loop so that
it will also look at a window's parent, if the event is a
''<PropertyNotify>'' event. The relevant part of the Tk event loop
currently looks like this:

|
|winPtr = (TkWindow *) Tk_IdToWindow(eventPtr->xany.display, handlerWindow);
|if (winPtr == NULL) {
|    if (eventPtr->type == PropertyNotify) {
|	TkSelPropProc(eventPtr);
|    }
|    return;
|}
|

If the flag for propagating ''<PropertyNotify>'' events is
''TK_PROP_PROPCHANGE'', then the code above must be modified to look
approximately like this:

|
|winPtr = (TkWindow *) Tk_IdToWindow(eventPtr->xany.display, handlerWindow);
|if (winPtr == NULL) {
|    if (eventPtr->type != PropertyNotify) {
|	return;
|    }
|    TkSelPropProc(eventPtr);
|    parentXId = (parent of handlerWindow);
|    winPtr = (TkWindow *) Tk_IdToWindow(eventPtr->xany.display, parentXId);
|    if (winPtr == NULL) {
|	return;
|    }
|    if (!(winPtr->flags & TK_PROP_PROPCHANGE)) {
|	return;
|    }
|    handlerWindow = parentXId;
|    return;
|}
|

~ Patches

A patch (against tk8.4a2) that implements the changes described aboves
may be found at

 > http://www.eecs.umich.edu/~mckay/wmenablers.patch.gz

~ Notes

Andreas Kupries. There was a ''tkwm' patch once. See the following urls for more: http://www.neosoft.com/tcl/ftparchive/sorted/x11/tkwm/ and http://www.ensta.fr/internet/unix/window_managers/tkwm.html

~ Copyright

This document is in the public domain.
Deleted tip/48.tip.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180




















































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TIP:            48
Title:          Basic themeing infrastructure for Tk
Version:        $Revision: 1.3 $
Author:         Fr�d�ric Bonnet <[email protected]>
State:          Draft
Type:           Project
Vote:           Pending
Created:        23-Jul-2001
Post-History:   
Discussions-To: news:comp.lang.tcl
Tcl-Version:    8.4

~ Abstract

The Tk Toolkit is one of the last major GUI toolkits lacking themes support.
This TIP proposes several simple changes that would allow for basic
themeability to be easily and progressively implemented without loss of
compatibility.

~ Background

The Tk Toolkit appeared on X-Window systems at a time where Motif was the de
facto standard for GUI development. It thus naturally adopted Motif's
look&feel and its famous 3d border style. First ports to non-X platforms
such as Windows and MacOS kept the Motif style, which disappointed many
users who felt Tk applications look "foreign". Version 8.0 released around
1996 added native look&feel on these platforms.

Recently, other Open Source toolkits such as QT (used by the KDE project)
and Gtk (used by the GIMP graphics editing software and the Gnome project)
emerged as powerful and free alternatives to Motif for X-Window GUI
development. The rapidly growing success of Open Source systems such as
GNU/Linux helped both toolkits attract a vast community of developers, and
the firm (and sometimes friendly) competition between both communities led
to an explosion of new features. Thirst for freedom and customizability
created the need for themeability.

The current implementation of Tk only provides native look&feel on supported
platforms (Windows, X-Window, MacOS). This lack partly explains Tk's loss of
mindshare, especially amongst Linux developers, where theme support is
considered a "cool" or must-have feature. 

While yesterday's goal of many GUIs was cross-platform visual uniformity (QT
and Gtk borrowed much of their visual appearance to Windows, which borrowed
earlier to NeXTStep), it is now quite common to find huge visual differences
on today's desktops, even on same systems. Screenshot contests are quite
common nowadays.

~ Rationale

Tk first kept away from the toolkit war. Tk's and its competitors'
philosophies are radically opposite. Tk favors high level abstractions and
scripting languages such as Tcl, whereas QT and Gtk developments are
primarily done using C or C++ (which Tcl/Tk advocates believe to be The
Wrong Way). But despite Tk's power, flexibility and ease of use, it has lost
serious mindshare, especially amongst newcomers and Linux users who don't
care about its cross-platform capabilities.

Many Tk users may see themes support as cosmetic or of lower importance than
much needed features suc as megawidgets or objectification. Nevertheless,
this is a critical feature to be implemented for the long-term viability of
Tk. Many courses are now promoting QT, Gtk or (aarggg!) Swing in place of
Motif, leaving no room to Tk. Whatever its qualities (cross-platform,
performance, ease of use, internationalization and Unicode support), the
lack of themeability will always be seen as one of the main reasons for not
using Tk. Applications using Tk instead of Gtk will look as "foreign" on
pixmap-themed Linux desktop, or even on newer MacOS and Windows versions, as
pre-8.0 applications were on non-X desktops.

The lack of themeability is neither a fatality nor difficult to solve. Tk
already allows for colors, fonts and border width and relief to be specified
for all widgets. What is currently missing is pixmap themeing and border
styles. The current proposal describes the needed building blocks for theme
support that are both easy to implement and backward compatible.

A straightforward solution would be that introduced by the Dash-patch in the
form of new widget options such as ''-tile''. But this approach suffers from
several major drawbacks:

  * A lot of new options are needed to handle the many ways of drawing
    pixmap tiles, such as anchoring, repeating, or scaling.

  * With the introduction of new options such as
    ''-activebackground'', tile-related options must be duplicated for
    each widget state (normal, active, disabled...), thus cluttering
    the options namespace a little more and raising the learning
    curve.

  * Applying a theme to a whole widget hierarchy implies traversing
    the whole tree and applying a lot of options to each widget.

  * Memory consumption is mechanically increased for all widgets, even
    in the case when these options are not used.

Careful examination of the current implementation shows that Tk aready
provides a simple and extensible mechanism for theme handling. Most widgets
use the same 3D border drawing code, which is gathered in a limited number
of files (generic/tk3d.{c|h} and <platform>/tk<platform>3d.{c|h}). This code
is used under the hood by options such as ''-background'', which accept
color values like ''-foreground'' but actually create ''Tk_3DBorder''s
instead of ''XColor''s. By extending the current code and allowing
script-level access to border objects, one gets a flexible, powerful and
easy to use themeing mechanism. Combined with the standard option database
mechanism, we get ready-to-use and well known theme file formats in the form
of Tcl scripts or X resource files. Further theme-related changes being made
on border objects rather than on widgets, backward and upward compatibility
is guaranteed. Border objects will give the same benefits as current font
objects. Similar enhancements may be done to color handling by creating
color objects.

~ Proposal

This document proposes the creation of a new Tk command ''border'', similar
in functionality to the existing ''font'' command. This command will allows
for border objects to be created and configured. Moreover, by rewriting the
current border handling APIs such ''Tk_Get3DBorder'' in a compatible way to
accept both colors and border object, all widgets using borders gain
immediate access to the new feature without needing to be rewritten. No new
feature is introduced by this document, such as pixmap tiling or border
style, but the clean separation between widgets and border handling will
allow for easier implementation of such features in future versions.

~ Specification

The new ''border'' command closely follows the existing ''font'' command,
both in use and behavior. It provides ''configure'', ''create'', ''delete''
and ''names'' subcommands. For now, border objects only have one options,
''-background'', that gives the same functionality as the existing
implementation (ie give the base color for 3d border drawing).

Like with fonts, any change to a given border object is propagated to all
widgets using this border.

~ Compatibility

The changes have implications that are very similar to that introduced by
the new font mechanism in Tk 4.2.

No extra widget option is introduced. Existing API functionalities are
exposed at script level. The current behavior is extended: existing border
objects take precedence over color names for procedures such as
''Tk_Get3DBorder''. Any code using the standard public API should need no
change at all. Code accessing internal structures may need to be rewritten.

~ Related Ideas / Future Work

Similar work can be done on colors. In the current implementation, colors
are either RGB triplets or fixed color names. Color objects would give a
higher flexibility and themeability:  allowing the definition of abstract
colors, propagating changes to a whole widget hierarchy, or using alternate
color spaces such as Lab, Yuv, CMYK... Contrary to borders, there is no
color object available in Tk, and XColors are used directly, so this implies
incompatible (but needed) changes.

The goal of the present TIP is to provide the building blocks needed to
easily implement theme-related features such as pixmap tiling or shaped
windows, by separating widget options for actual border management. The only
option supported by the current proposal, ''-background'', offers no new
feature with respect to the current implementation. Future enhancements and
extensions are expected to introduce new options for this purpose. Future
options may cover the following features:

  1.	Border style: allow choice between predefined or user-provided
	border styles, such as Motif, Windows, MacOS... Distinct code
	may be provided for all the supported reliefs.

  2.	Pixmap tiling: images (with potentially transparent areas) will
	be specified for the various elements of the border: sides,
	center, corners.  Several display methods may be available,
	such as anchoring, repeating and stretching. An alternative is
	to supply a single image and specify areas to use for the
	various elements.

  3.	Procedural drawing: gradients, textures...

  4.	Shaped windows.

~ Copyright

This document has been placed in the public domain.
Deleted tip/49.tip.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100




































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TIP:          49
Title:        I/O Subsystem: Add API Tcl_OutputBuffered(chan)
Version:      $Revision: 1.3 $
Author:       Rolf Schroedter <[email protected]>
State:        Accepted
Type:         Project
Vote:         Done
Created:      25-Jul-2001
Post-History:
Tcl-Version:  8.4

~ Abstract

This document proposes the new public function ''Tcl_OutputBuffered()'',
analogous to the existing public function ''Tcl_InputBuffered()''.

~ Rationale

Tcl has a ''Tcl_InputBuffered()'' function but no analog
function for the output buffer. 
A ''Tcl_OutputBuffered()'' function would be useful
for non-blocking channel drivers which need to know the 
number of bytes pending in Tcl's output queue.

The implementation of [35] allows one to query the number of bytes 
in the channels input and output queues with a ''[fconfigure -queue]''
option. This is a useful feature especially for serial ports
because the input/output may be really slow or even stall.

On the driver level only the number of bytes in the system queue
can be queried. For a non-blocking channel there may also be
some pending output in Tcl buffers. 
Obviously there is not much sense to know only the byte counter
at driver level without knowing ''Tcl_OutputBuffered()''.

~ Related Ideas

It could also be useful to add general ''[fconfigure -inputbuffer
-outputbuffer]'' options for all channels returning the values from
''Tcl_InputBuffered(chan)'' and ''Tcl_OutputBuffered(chan)'' respectively.

At this opportunity the code of ''Tcl_Seek()'' and ''Tcl_Tell()''
may be shortened, because it repeats the code of 
''Tcl_InputBuffered()'' and ''Tcl_OutputBuffered()''.

~ Implementation

This function would be added to ''generic/tclIO.c'' and be 
stubs enabled. This new API should not have any impact
on existing applications.

The implementation is analog to what is done in ''Tcl_Tell()'':

|
|/*
| *----------------------------------------------------------------------
| *
| * Tcl_OutputBuffered --
| *
| *	Returns the number of bytes of output currently buffered in the
| *	common internal buffer of a channel.
| *
| * Results:
| *	The number of output bytes buffered, or zero if the channel is not
| *	open for writing.
| *
| * Side effects:
| *	None.
| *
| *----------------------------------------------------------------------
| */
|
|int
|Tcl_OutputBuffered(chan)
|    Tcl_Channel chan;			/* The channel to query. */
|{
|    ChannelState *statePtr = ((Channel *) chan)->state;
|					/* State of real channel structure. */
|    ChannelBuffer *bufPtr;
|    int bytesBuffered;
|
|    for (bytesBuffered = 0, bufPtr = statePtr->outQueueHead;
|	bufPtr != (ChannelBuffer *) NULL;
|	bufPtr = bufPtr->nextPtr) {
|	bytesBuffered += (bufPtr->nextAdded - bufPtr->nextRemoved);
|    }
|    if ((statePtr->curOutPtr != (ChannelBuffer *) NULL) &&
|	    (statePtr->curOutPtr->nextAdded > statePtr->curOutPtr->nextRemoved)) {
|        statePtr->flags |= BUFFER_READY;
|        bytesBuffered +=
|            (statePtr->curOutPtr->nextAdded - statePtr->curOutPtr->nextRemoved);
|    }
|    return bytesBuffered;
|}
|

~ Copyright

This document has been placed in the public domain.

Deleted tip/50.tip.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186


























































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TIP:            50
Title:          Bundle [incr Tcl] with the Core Tcl distribution
Version:        $Revision: 1.8 $
Author:         Kevin Kenny <[email protected]>
Author:         Mark Harrison <[email protected]>
Author:         Jeff Hobbs <[email protected]>
Author:         Andreas Kupries <[email protected]>
Author:         Karl Lehenbauer <[email protected]>
Author:         Michael McLennan <[email protected]>
Author:         Don Porter <[email protected]>
Author:         Brent Welch <[email protected]>
State:          Accepted
Type:           Project
Vote:           Done
Created:        27-Jul-2001
Post-History:   
Tcl-Version:    8.4

~ Abstract

A "town meeting" discussion in which users were given the opportunity
to question the Tcl Core Team at the 2001 Open Source Convention has
revealed a great popular demand for bundling an object system with the
distribution of the Tcl Core.  This TIP presents a compromise proposal
for including [[incr Tcl]] that was acceptable to all eight TCT members
present.

~ Proposal

   * [[incr Tcl]] (http://tcltk.com/itcl/) shall be bundled with the core
     Tcl distribution.

   * [[incr Tcl]] shall be "included" in the Core in only a weak
     sense.

      > The location of the [[incr Tcl]] source tree shall be left to
        the discretion of the affected maintainers.  (It appears likely
        that most [[incr Tcl]] source will appear in a separate
        ''itcl'' directory parallel to the ''generic'', ''mac'',
        ''unix'' and ''win'' directories in the source.)

      > [[incr Tcl]] shall be built as a separate loadable package, 
        similar to the ''dde'', ''http'', ''msgcat'', and ''registry'' 
        packages.  

      > The ''::itcl'' namespace shall be the only new component 
        included in the global namespace, and shall appear only when 
        a script executes

|               package require Itcl

      > There shall be no ''::class'' command in the Core.

      > The ''::info'' command shall not provide any subcommands
        specific to [[incr Tcl]].

   * [[incr Tcl]] shall not be substantially modified under the scope
     of this TIP.

      > The existing issues surrounding errors thrown from object
        destructors shall not be addressed.

      > The existing use of ''rename'' for object destruction shall
        not be amended.

      > All other limitations of [[incr Tcl]] are initially accepted
        as they are.

      > Of course, additional TIPs could be submitted to modify
        [[incr Tcl]] as desired!

   * The TCT shall assume the role of ''gatekeeper'' for changes to
     the functionality of [[incr Tcl]].

      > Changes that affect user-visible functionality of [[incr Tcl]]
        shall be made through the TIP process.

      > Informational TIPs identifying maintainer areas and assigning
        maintainers to them shall be developed.

   * Nothing in this TIP shall be construed as identifying [[incr
     Tcl]] as a single preferred object system for Tcl.  If the
     community desires other systems such as OTcl, XOTcl, or ObjecTcl
     to stand on an equal footing to [[incr Tcl]], their champions
     can introduce TIPs similar to this one.

   * [[incr Tk]] and [[incr widgets]] are outside the scope of this TIP.

~ Rationale

The lack of a standard object and data abstraction system continues to
hinder Tcl development.

  > "Lets face it, not including any sort of OO system is one of
    the major failings of Tcl. Indexing into global arrays is
    a sad hack when compared to a real OO system."
           ''- Mo DeJong <[email protected]>''

Moreover, the argument that "Tcl is not object oriented" continues to
hamper Tcl marketing.  Including at least one object system with the
Tcl core, so that it is dependably available unless the user has built
from source, would address this objection.

Since an earler proposal ([6]) to incorporate [[incr Tcl]] into the
Core failed to garner the necessary votes, at least in part because
participants were uncertain of the rationales, it seems wise to
discuss the individual points in further detail.

   * All agree that some sort of object system must be bundled with
     the core so that it is dependably available.  [[incr Tcl]]
     appears to be the most popular of the existing systems, as well
     as the most familiar to the current TCT, making it the most
     attractive of several candidates for this role.

   * The original [[incr Tcl]] developers have pointed out that
     bundling in the Core would facilitate [[incr Tcl]] development
     greatly.  While it is a separate loadable package, [[incr Tcl]]
     is intimate with the core, depending on many undocumented
     interfaces to carry out its functions.  Integrating it with the
     Core would make it easier to maintain.

   * Including a ''::class'' command in the Core is not acceptable at
     this time, because it would have the effect of disenfranchising
     the users of other object systems -- who are too numerous to
     ignore.  Moreover, the ability of Tcl to serve as a test platform
     for novel object models must not be compromised.

   * Similarly, integrating [[incr Tcl]] closely with commands such as
     ''::info'' or ''::destroy'' would accord it a privileged status
     that the users of other object systems are reluctant to accept.

   * [[incr Tcl]] is what it is.  It would be inappropriate to demand
     that all the perceived shortcomings of the [[incr Tcl]] system be
     addressed prior to inclusion in the Core.  The TIP process is
     available to make further changes; the system is certainly good
     enough that many thousands of programmers use it daily.

   * If [[incr Tcl]] is to be included in the Core, then common sense
     requires that it be under control of the TIP process.

~ Alternatives

   * Include [[incr Tcl]] in a "batteries included" (BI) distribution.

      > Many people will not opt for the BI distribution ([4]) due to its
        larger size.  It is quite likely that (for example) a Linux
        distribution my include Tcl as a standard component, but place the BI
        on a supplemental disk.

      > Moreover, as mentioned above, the [[incr Tcl]] sources are
        already intimate with the Tcl core; there are great
        maintenance savings to be achieved by combining the source
        distributions. 

   * Integrate [[incr Tcl]] tightly into the Tcl Core.

      > This alternative is unacceptable to a good many users.  A
        number of attendees at the 2001 Open Source Convention
        mentioned specifically that they use alternative object
        systems such as OTcl.  These users would be essentially
        disenfranchised if, for instance, a ''::class'' command were to
        appear in the Core.

~ Implementation

Jeff Hobbs has volunteered to lead the implementation effort with
the assistance of all volunteers who want to help.

~ Notes

Eight members of the Tcl Core Team (Harrison, Hobbs, Kenny, Kupries,
Lehenbauer, McLennan, Porter and Welch) agreed orally to this proposal
at the 2001 Open Source Convention.  Since not all have had the
opportunity to read the formal written version of the proposal, that
vote shall not be considered binding.

~ References

   * http://tcltk.com//itcl

   * [6]

~ Copyright

This document has been placed in the public domain.

Deleted tip/51.tip.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
















































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TIP:            51
Title:          Native Menubutton on Macintosh
Version:	$Revision: 1.1 $
Author:         Mats Bengtsson <[email protected]>
State:          Draft
Type:           Project
Tcl-Version:    8.4
Vote:           Pending
Created:        04-Aug-2001
Post-History:

~ Abstract

This is a replacement for the menubutton on the Macintosh with a
native implementation which is compliant with the Appearance Manager
in Mac OS 8 and later.

~ Rationale

The present (in 8.3.3 and earlier) menubutton on the Macintosh is
implemented using Tk drawing to draw something similar to the native
menubutton on Mac how it looks on Pre Mac OS 8.0 systems, and
therefore fails to give the correct appearance on Mac OS 8.0 systems
and later. This TIP presents a step to increase the native appearance
on the Macintosh (similar to [25].)

#image:51compare Comparison of Native (to left) and Standard Menu Buttons.

~ Reference Implementation

The proposed change is now implemented as a loadable extension (in C)
on Macintosh, and can be downloaded at
http://hem.fyristorg.com/matben/download/MacMenuButton.sit This
implementation differs from the other buttons in Mac Tk (button,
radiobutton, checkbutton), which use a mixture of native Apple drawing
code and Tk drawing code, since it uses only native Apple code for
drawing.  This extension requires Tcl/Tk 8.3.2p1 or later due to the
changed stub loading mechanism. The new implementation is not a
complete replacement since it lacks the ''-bitmap'' and ''-image''
options, and a few other things, see below.

The changes necessary are:

    * Replace the ''tkMacMenubutton.c'' file with the new one.

    * Add a MENU resource item, which is included in the shared library,
      but needs to be added to the core.

    * Modifications to ''tkMacFont.c'' (see appendix). Put declaration
      so it can be used from any file. Possibly also add the new
      function to the stub table since it can be practical for other
      extension writers.

    * Need to check for the presence of the Appearance manager:

|if (TkMacHaveAppearance()) 
|   use native (new) menubutton 
|else 
|   use present menubutton

All functionality from the documentation that is applicable is
implemented in the extension, with some exceptions:

    * The ''-image'' and ''-bitmap'' options are not supported, yet.
    
    * There is no button pressed (SELECTED) flag so it highlights when
      the mouse enters, just as a reminder that it must be fixed.
      (see appendix)
        
    * Don't know which color to pick for the three pixels in each
      corner.  It is now the ''-background'' color, but the ordinary
      button uses ''-highlightbackground''?
    
    * The position of the popup menu should be changed in order to
      conform better with standard Mac appearance..
    
    * Something needs to be done so that we can get Mac native font
      stuffs from a ''Tk_Font'' object; I've included a crude hack in
      the appendix.
        
    * It is compliant to the Appearance Manager which means that
      foreground and background colors are set via themes and not from
      command switches.

    * Minor differences to comply with the Appearance Manager.

All these deviations are consistent with the look-and-feel of Mac OS
8.0 and on. Existing scripts using menubutton are compatible with the
new menubutton.

Open questions: 

    * Option to use for the color of the corner pixels.

    * If (and how) a SELECTED flag should be added to
      ''tkMenuButton.h'', and code to support it in
      ''tkMenuButton.c''.

    * Implementation of the ''-bitmap'' and ''-image'' options.

    * A ''-compound'' option as described in TIP #11.

~ Copyright

This document has been placed in the public domain.

~ Appendix

    * Addition to ''tkMenuButton.h'':

|#define SELECTED		8

    > Other modifications to tkMenuButton.c must be made to support
      this flag.

    * Addition to ''tkMacFont.c'' (possibly add to exported
      functions):

|/*
| *---------------------------------------------------------------------------
| *
| * GetMacFontAttributes -- 
| *
| *      Takes a Tk_Font and gets the Mac font attributes faceNum, size, and style.
| *      Note that the Mac font size is in pixels while the Tk_Font size is
| *      in points. No need to do any UTF-8 translations since this is
| *      implicit in GetFamilyOrAliasNum().
| *      The code here is essentially a modified TkpGetFontFromAttributes() and
| *      InitFont(), both from tkMacFont.c.
| *
| * Results:
| *      Sets the Mac font attributes.
| *
| * Side effects:
| *      None.
| *
| *---------------------------------------------------------------------------
| */
|void
|GetMacFontAttributes(
|        Tk_Window tkwin,        /* Tk window. (in) */
|        Tk_Font tkFont,         /* Tk font. (in) */
|        short *faceNumPtr,      /* Mac font face id. (out) */
|        short *macSizePtr,      /* Mac font size in pixels. (out) */
|        Style *stylePtr)        /* Mac font style specifier. (out) */
|{
|    int i, j;
|    char *faceName, *fallback;
|    char ***fallbacks;
|    MacFont *fontPtr;
|    const TkFontAttributes *faPtr;
|    int size;           /* Size in points. */
|        
|    /*
|     * This is just a macro to access the attribute struct member.
|     */
|     
|    faPtr = GetFontAttributes(tkFont);
|
|    /*
|     * Algorithm to get the closest font to the one requested.
|     *
|     * try fontname
|     * try all aliases for fontname
|     * foreach fallback for fontname
|     *      try the fallback
|     *      try all aliases for the fallback
|     */
|     
|    *faceNumPtr = 0;
|    faceName = faPtr->family;
|    if (faceName != NULL) {
|        if (GetFamilyOrAliasNum(faceName, faceNumPtr) != 0) {
|            goto found;
|        }
|        fallbacks = TkFontGetFallbacks();
|        for (i = 0; fallbacks[i] != NULL; i++) {
|            for (j = 0; (fallback = fallbacks[i][j]) != NULL; j++) {
|                if (strcasecmp(faceName, fallback) == 0) {
|                    for (j = 0; (fallback = fallbacks[i][j]) != NULL; j++) {
|                        if (GetFamilyOrAliasNum(fallback, faceNumPtr)) {
|                            goto found;
|                        }
|                    }
|                }
|                break;
|            }
|        }
|    }
|    
|    found:    
|    *stylePtr = 0;
|    if (faPtr->weight != TK_FW_NORMAL) {
|        *stylePtr |= bold;
|    }
|    if (faPtr->slant != TK_FS_ROMAN) {
|        *stylePtr |= italic;
|    }
|    if (faPtr->underline) {
|        *stylePtr |= underline;
|    }
|    if (faPtr->size == 0) {
|        size = -GetDefFontSize();
|    } else {
|        size = faPtr->size;
|    }
|    *macSizePtr = (short) TkFontGetPixels(tkwin, size);
|}
Deleted tip/51compare.eps.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
%!PS-Adobe-3.0 EPSF-3.0
%%Title: 51compare.eps
%%Creator: ImageMagick
%%CreationDate: Thu Aug  9 13:42:47 2001
%%BoundingBox: 0 0 413 275
%%Pages: 0
%%EndComments
%%BeginProlog
%
% Display a color image.  The image is displayed in color on
% Postscript viewers or printers that support color, otherwise
% it is displayed as grayscale.
%
/buffer 512 string def
/byte 1 string def
/color_packet 3 string def
/pixels 768 string def

/DirectClassPacket
{
  %
  % Get a DirectClass packet.
  %
  % Parameters:
  %   red.
  %   green.
  %   blue.
  %   length: number of pixels minus one of this color (optional).
  %
  currentfile color_packet readhexstring pop pop
  compression 0 gt
  {
    /number_pixels 3 def
  }
  {
    currentfile byte readhexstring pop 0 get
    /number_pixels exch 1 add 3 mul def
  } ifelse
  0 3 number_pixels 1 sub
  {
    pixels exch color_packet putinterval
  } for
  pixels 0 number_pixels getinterval
} bind def

/DirectClassImage
{
  %
  % Display a DirectClass image.
  %
  systemdict /colorimage known
  {
    columns rows 8
    [
      columns 0 0
      rows neg 0 rows
    ]
    { DirectClassPacket } false 3 colorimage
  }
  {
    %
    % No colorimage operator;  convert to grayscale.
    %
    columns rows 8
    [
      columns 0 0
      rows neg 0 rows
    ]
    { GrayDirectClassPacket } image
  } ifelse
} bind def

/GrayDirectClassPacket
{
  %
  % Get a DirectClass packet;  convert to grayscale.
  %
  % Parameters:
  %   red
  %   green
  %   blue
  %   length: number of pixels minus one of this color (optional).
  %
  currentfile color_packet readhexstring pop pop
  color_packet 0 get 0.299 mul
  color_packet 1 get 0.587 mul add
  color_packet 2 get 0.114 mul add
  cvi
  /gray_packet exch def
  compression 0 gt
  {
    /number_pixels 1 def
  }
  {
    currentfile byte readhexstring pop 0 get
    /number_pixels exch 1 add def
  } ifelse
  0 1 number_pixels 1 sub
  {
    pixels exch gray_packet put
  } for
  pixels 0 number_pixels getinterval
} bind def

/GrayPseudoClassPacket
{
  %
  % Get a PseudoClass packet;  convert to grayscale.
  %
  % Parameters:
  %   index: index into the colormap.
  %   length: number of pixels minus one of this color (optional).
  %
  currentfile byte readhexstring pop 0 get
  /offset exch 3 mul def
  /color_packet colormap offset 3 getinterval def
  color_packet 0 get 0.299 mul
  color_packet 1 get 0.587 mul add
  color_packet 2 get 0.114 mul add
  cvi
  /gray_packet exch def
  compression 0 gt
  {
    /number_pixels 1 def
  }
  {
    currentfile byte readhexstring pop 0 get
    /number_pixels exch 1 add def
  } ifelse
  0 1 number_pixels 1 sub
  {
    pixels exch gray_packet put
  } for
  pixels 0 number_pixels getinterval
} bind def

/PseudoClassPacket
{
  %
  % Get a PseudoClass packet.
  %
  % Parameters:
  %   index: index into the colormap.
  %   length: number of pixels minus one of this color (optional).
  %
  currentfile byte readhexstring pop 0 get
  /offset exch 3 mul def
  /color_packet colormap offset 3 getinterval def
  compression 0 gt
  {
    /number_pixels 3 def
  }
  {
    currentfile byte readhexstring pop 0 get
    /number_pixels exch 1 add 3 mul def
  } ifelse
  0 3 number_pixels 1 sub
  {
    pixels exch color_packet putinterval
  } for
  pixels 0 number_pixels getinterval
} bind def

/PseudoClassImage
{
  %
  % Display a PseudoClass image.
  %
  % Parameters:
  %   class: 0-PseudoClass or 1-Grayscale.
  %
  currentfile buffer readline pop
  token pop /class exch def pop
  class 0 gt
  {
    /grays columns string def
    columns rows 8
    [
      columns 0 0
      rows neg 0 rows
    ]
    { currentfile grays readhexstring pop } image
  }
  {
    %
    % Parameters:
    %   colors: number of colors in the colormap.
    %   colormap: red, green, blue color packets.
    %
    currentfile buffer readline pop
    token pop /colors exch def pop
    /colors colors 3 mul def
    /colormap colors string def
    currentfile colormap readhexstring pop pop
    systemdict /colorimage known
    {
      columns rows 8
      [
        columns 0 0
        rows neg 0 rows
      ]
      { PseudoClassPacket } false 3 colorimage
    }
    {
      %
      % No colorimage operator;  convert to grayscale.
      %
      columns rows 8
      [
        columns 0 0
        rows neg 0 rows
      ]
      { GrayPseudoClassPacket } image
    } ifelse
  } ifelse
} bind def

/DisplayImage
{
  %
  % Display a DirectClass or PseudoClass image.
  %
  % Parameters:
  %   x & y translation.
  %   x & y scale.
  %   image label.
  %   image columns & rows.
  %   class: 0-DirectClass or 1-PseudoClass.
  %   compression: 0-RunlengthEncodedCompression or 1-NoCompression.
  %   hex color packets.
  %
  gsave
  currentfile buffer readline pop
  token pop /x exch def
  token pop /y exch def pop
  x y translate
  currentfile buffer readline pop
  token pop /x exch def
  token pop /y exch def pop
  /NewCenturySchlbk-Roman findfont 24 scalefont setfont
  currentfile buffer readline pop
  0 y 12 add moveto buffer show pop
  x y scale
  currentfile buffer readline pop
  token pop /columns exch def
  token pop /rows exch def pop
  currentfile buffer readline pop
  token pop /class exch def pop
  currentfile buffer readline pop
  token pop /compression exch def pop
  class 0 gt { PseudoClassImage } { DirectClassImage } ifelse
  grestore
} bind def
%%EndProlog
%%Page:  1 1
userdict begin
%%BeginData:
DisplayImage
0 0
413 275
            
413 275
1
0
0
256
ffffff
ffffff
ffffff
ffffff
ffffff
ffffff
ffffff
ffffff
ffffff
ffffff
ffffff
ffffff
ffffff
ffffff
ffffff
ffffff
ffffff
ffffff
ffffff
efefef
efefef
efefef
efefef
efefef
efefef
efefef
efefef
efefef
efefef
efefef
efefef
efefef
efefef
efefef
efefef
efefef
efefef
efefef
dedede
dedede
dedede
dedede
dedede
dedede
dedede
dedede
dedede
dedede
dedede
dedede
dedede
dedede
dedede
dedede
dedede
dedede
cecece
cecece
cecece
cecece
cecece
cecece
cecece
cecece
cecece
cecece
cecece
cecece
cecece
cecece
cecece
cecece
cecece
cecece
bdbdbd
bdbdbd
bdbdbd
bdbdbd
bdbdbd
bdbdbd
bdbdbd
bdbdbd
bdbdbd
bdbdbd
bdbdbd
bdbdbd
bdbdbd
bdbdbd
bdbdbd
bdbdbd
bdbdbd
bdbdbd
adadad
adadad
adadad
adadad
adadad
adadad
adadad
adadad
adadad
adadad
adadad
adadad
adadad
adadad
adadad
adadad
adadad
adadad
9c9c9c
9c9c9c
9c9c9c
9c9c9c
9c9c9c
9c9c9c
9c9c9c
9c9c9c
9c9c9c
9c9c9c
9c9c9c
9c9c9c
9c9c9c
9c9c9c
9c9c9c
9c9c9c
9c9c9c
9c9c9c
8c8c8c
8c8c8c
8c8c8c
8c8c8c
8c8c8c
8c8c8c
8c8c8c
8c8c8c
8c8c8c
8c8c8c
8c8c8c
8c8c8c
8c8c8c
8c8c8c
8c8c8c
8c8c8c
8c8c8c
8c8c8c
737373
737373
737373
737373
737373
737373
737373
737373
737373
737373
737373
737373
737373
737373
737373
737373
737373
737373
636363
636363
636363
636363
636363
636363
636363
636363
636363
636363
636363
636363
636363
636363
636363
636363
636363
636363
525252
525252
525252
525252
525252
525252
525252
525252
525252
525252
525252
525252
525252
525252
525252
525252
525252
525252
424242
424242
424242
424242
424242
424242
424242
424242
424242
424242
424242
424242
424242
424242
424242
424242
424242
424242
212121
212121
212121
212121
212121
212121
212121
212121
212121
212121
212121
212121
212121
212121
212121
212121
212121
212121
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
000000
263e92012604920126019201260192022600920126019201260492012601920126019201
260192012601920126e4b6010046263e9201260492012601920126019201260192012601
9202260392012601920126019201260192012601920126e4b60100462601ecffec960003
2601ec0000ff00933800ec0000032601ec00000038ff38926e00ec0100022601ec000000
38ff38926e00ec0100022601ec0000003801800b380400a2382400933804800b3803800b
38026e00ec0100022601ec00000038018000da0a0000380492a23824929338038000da0a
000038028000da0a000038016e00ec0100022601ec00000038018000da0000003807da00
0000380300a23803ec013802ec013802ec013800ec013808ec013806009338048000da00
00003803da003802da00000038028000da0000003807da00000038016e00ec0100022601
ec00000038018000da0038006e015c014a0138008000da000000380492a23802ec013802
ec013802ec00380cec013807929338038000da0038006e015c01da004a0038008000da00
000038028000da0038006e015c014a0138008000da00000038016e00ec0100022601ec00
000038018000da0038006e005c014a0138018000da000000380300a23803ec013802ec01
3802ec003801ec013802ec033801ec013800ec013803009338048000da0038006e005c01
4a00da0038018000da00000038028000da0038006e005c014a0138018000da0000003801
6e00ec0100022601ec00000038018000da0038005c014a01380126008000da0000003804
92a23803ec013800ec033800ec013801ec013801ec013804ec023800ec01380392933803
8000da0038005c014a01da00380026008000da00000038028000da0a000038016e00ec01
0002b601ec00000038018000da0038005c004a01380126018000da000000380300a23804
ec013800ec003800ec013800ec003802ec013801ec023803ec013801ec01380200933804
8000da0038005c004a013800da0026018000da00000038028000da0038005c004a013801
26018000da00000038016e00ec010004ec00000038018000da0038004a01380126011300
8000da000000380492a23803ec033800ec033802ec013802ec023802ec013801ec013803
929338038000da06260013008000da00000038028000da0a000038016e00ec010004ec00
000038018000da0038004a003801260113018000da000000380300a23805ec013802ec01
3803ec013803ec023801ec013801ec013802009338048000da0038004a00380126011301
8000da00000038028000da0038004a003801260113018000da00000038016e00ec010004
ec00000038018000da0038022601130100008000da000000380492a23804ec013802ec01
3803ec013804ec013801ec013801ec013803929338038000da0038022601130100008000
da00000038028000da0038022601130100008000da00000038016e00ec010004ec000000
38018000da0038008007da000000380300a23805ec013802ec013803ec013801ec033802
ec013801ec013802009338048000da0038008007da00000038028000da0038008007da00
000038016e00ec010004ec00000038018000da0a0000380492a23824929338038000da0a
000038028000da0a000038016e00ec010004ec0000003802000b38ff3865000b3803000b
38016e00ec010004ec00000038ff38926e00ec010004ec00000038ff38926e00ec010004
ec00000038ff38926e00ec010004ec00000038016eff6e8d38026e00ec010004ec000000
38016e00ecffec8c000038016e00ec010004ec00000038016e00ec0026f50094ec000000
38016e00ec010004ec00000038016e00ec0026f50094ec00000038016e00ec010004ec00
000038016e00ec0026f50094ec00000038016e00ec010004ec00000038016e00ec0026f5
0094ec00000038016e00ec010004ec00000038016e00ec002615da00ecafda00262d0094
ec00000038016e00ec010004ec00000038016e00ec002614ec00009d26124a00ec00262c
0094ec00000038016e00ec010004ec00000038016e00ec002613da000000269d5c002600
001026005c00da00262b0094ec00000038016e00ec010004ec00000038016e00ec002613
ec000000269d5c0026000000260f5c009200ec00262b0094ec00000038016e00ec010004
ec00000038016e00ec002613ec000000269d5c0026000000260f5c009200ec00262b0094
ec00000038016e00ec010004ec00000038016e00ec002613ec0000002604ec012605ec01
2609ec00260eec03260cec012601ec012613ec052607ec0126395c00260000002606ec00
26075c009200ec00262b0094ec00000038016e00ec010004ec00000038016e00ec002613
ec0000002604ec012605ec012608ec01260dec012601ec00260cec012619ec012609ec01
26395c00260000002605ec0226065c009200ec00262b0094ec00000038016e00ec010004
ec00000038016e00ec002613ec0000002604ec022603ec022601ec032601ec042601ec03
2604ec012605ec032603ec042601ec012601ec012600ec012603ec022600ec002605ec01
2603ec032601ec0126395c00260000002604ec0426055c009200ec00262b0094ec000000
38016e00ec010004ec00000038016e00ec002613ec0000002604ec022603ec022604ec01
2601ec012602ec012607ec012604ec012601ec012601ec012601ec012601ec012601ec02
2600ec012601ec012601ec012605ec012602ec012601ec002601ec0126395c0026000000
2603ec0626045c009200ec00262b0015ec680015ec00000038016e00ec010004ec000000
38016e00ec002613ec0000002604ec002600ec012601ec002600ec012601ec042601ec01
2602ec022606ec012604ec012601ec012601ec012601ec012601ec012601ec012601ec01
2601ec012601ec012605ec012602ec012604ec0126395c0026000000260f5c009200ec00
262b0015ec000066ec000015ec00000038016e00ec010004ec00000038016e00ec002613
ec0000002604ec002600ec012601ec002600ec012600ec012601ec012601ec012603ec02
2605ec012604ec012601ec012601ec012601ec012601ec012601ec012601ec012601ec01
2601ec012605ec012602ec012604ec0126395c0026000000260f5c009200ec00262b0015
ec000066ec000015ec00000038016e00ec010004ec00000038016e00ec002613ec000000
2604ec002601ec022601ec012600ec012601ec012601ec012604ec022604ec012604ec01
2601ec012601ec012601ec012601ec012601ec012601ec012601ec012601ec012605ec01
2602ec012604ec0126395c00260000002603ec0626045c009200ec00262b0015ec000066
ec010014ec00000038016e00ec010004ec00000038016e00ec002613ec0000002604ec00
2601ec022601ec012600ec012600ec022601ec012605ec012605ec012603ec012601ec01
2601ec012601ec012601ec012601ec012601ec012601ec012600ec022605ec012602ec01
2604ec0126395c00260000002604ec0426055c009200ec00262b0015ec000066ec010014
ec00000038016e00ec010004ec00000038016e00ec002613ec0000002604ec002602ec00
2602ec012601ec012600ec012602ec022600ec032607ec032601ec032603ec022600ec00
2601ec012601ec012601ec012602ec012600ec012605ec012603ec032601ec0126395c00
260000002605ec0226065c009200ec00262b0015ec000066ec010014ec00000038016e00
ec010004ec00000038016e00ec002613ec000000264dec01264d5c00260000002606ec00
26075c009200ec00262b0015ec000003ec010005ec010009ec00000eec03000cec010001
ec010013ec050007ec010003ec010014ec00000038016e00ec010004ec00000038016e00
ec002613ec000000264aec03264e5c0026000000260f5c009200ec00262b0015ec000003
ec010005ec010008ec01000dec010001ec00000cec010019ec010009ec010003ec010014
ec00000038016e00ec010004ec00000038016e00ec002613ec000000269d5c0026000000
260f5c009200ec00262b0015ec000003ec020003ec020001ec030001ec040001ec030004
ec010005ec030003ec040001ec010001ec010000ec010003ec020000ec000005ec010003
ec030001ec010003ec010014ec00000038016e00ec010004ec00000038016e00ec002613
da000000269d5c0026015c0f9201da00262b0015ec000003ec020003ec020004ec010001
ec010002ec010007ec010004ec010001ec010001ec010001ec010001ec010001ec020000
ec010001ec010001ec010005ec010002ec010001ec000001ec010003ec010014ec000000
38016e00ec010004ec00000038016e00ec002614ec005c9e4a009211ec00262c0015ec00
0003ec000000ec010001ec000000ec010001ec040001ec010002ec020006ec010004ec01
0001ec010001ec010001ec010001ec010001ec010001ec010001ec010001ec010005ec01
0002ec010004ec010003ec010014ec00000038016e00ec010004ec00000038016e00ec00
2615da00ecafda00262d0015ec000003ec000000ec010001ec000000ec010000ec010001
ec010001ec010003ec020005ec010004ec010001ec010001ec010001ec010001ec010001
ec010001ec010001ec010001ec010005ec010002ec010004ec010003ec010014ec000000
38016e00ec010004ec00000038016e00ec0026f50015ec000003ec000001ec020001ec01
0000ec010001ec010001ec010004ec020004ec010004ec010001ec010001ec010001ec01
0001ec010001ec010001ec010001ec010001ec010005ec010002ec010004ec010003ec01
0014ec00000038016e00ec010004ec00000038016e00ec0026f50015ec000003ec000001
ec020001ec010000ec010000ec020001ec010005ec010005ec010003ec010001ec010001
ec010001ec010001ec010001ec010001ec010001ec010000ec020005ec010002ec010004
ec010003ec010014ec00000038016e00ec010004ec00000038016e00ec0026f50015ec00
0003ec000002ec000002ec010001ec010000ec010002ec020000ec030007ec030001ec03
0003ec020000ec000001ec010001ec010001ec010002ec010000ec010005ec010003ec03
0001ec010003ec010014ec00000038016e00ec010004ec00000038016e00ec0026f50015
ec00004cec010017ec010014ec00000038016e00ec010004ec00000038016e00ec0026f5
0015ec000049ec030018ec010014ec00000038016e00ec010004ec00000038016e00ec00
26f50015ec000066ec010014ec00000038016e00ec010004ec00000038016e00ec0026f5
0015ec000066ec010014ec00000038016e00ec010004ec00000038016e00ec0026f50015
ec000066ec010014ec00000038016e00ec010004ec00000038016e00ec002615da00ec86
da0026560015ec690014ec00000038016e00ec010004ec00000038016e00ec002614ec00
0077260f4a00ec0026550018ec660014ec00000038016e00ec010004ec00000038016e00
ec002613da00000026775c002600000d26005c00da0026540094ec00000038016e00ec01
0004ec00000038016e00ec002613ec00000026775c0026000000260c5c009200ec002654
0094ec00000038016e00ec010004ec00000038016e00ec002613ec00000026775c002600
00002605ec0026055c009200ec0026540094ec00000038016e00ec010004ec0000003801
6e00ec002613ec0000002603ec012603ec012607ec01260cec03260aec012601ec012610
ec052607ec01261e5c00260000002604ec0226045c009200ec0026540094ec0000003801
6e00ec010004ec00000038016e00ec002613ec0000002603ec022601ec022607ec01260b
ec012601ec012609ec012616ec012609ec01261e5c00260000002603ec0426035c009200
ec0026540094ec00000038016e00ec010004ec00000038016e00ec002613ec0000002603
ec072601ec022601ec032601ec032604ec012605ec022602ec032601ec012600ec032602
ec032606ec012603ec022602ec01261e5c0026000000260c5c009200ec0026540094ec00
000038016e00ec010004ec00000038016e00ec002613ec0000002603ec012600ec012600
ec012603ec012601ec012601ec012607ec012604ec012600ec012600ec012600ec012601
ec012600ec012600ec012600ec012600ec012606ec012602ec012600ec012601ec01261e
5c0026000000260c5c009200ec0026540094ec00000038016e00ec010004ec0000003801
6e00ec002613ec0000002603ec012603ec012601ec032601ec012602ec022605ec012604
ec012600ec012600ec012600ec012601ec012600ec012600ec012600ec012600ec012606
ec012602ec012604ec01261e5c00260000002603ec0426035c009200ec0026540094ec00
000038016e00ec010004ec00000038016e00ec002613ec0000002603ec012603ec012600
ec012600ec012601ec012604ec012604ec012601ec012600ec012600ec012600ec012600
ec012601ec012600ec012600ec012600ec012600ec012606ec012602ec012600ec012601
ec01261e5c00260000002604ec0226045c009200ec0026540094ec00000038016e00ec01
0004ec00000038016e00ec002613ec0000002603ec012603ec012601ec032602ec012600
ec032606ec032602ec022602ec032601ec012600ec012600ec012601ec032606ec012603
ec022602ec01261e5c00260000002605ec0026055c009200ec0026540094ec0000003801
6e00ec010004ec00000038016e00ec002613ec0000002641ec0126335c0026000000260c
5c009200ec0026540094ec00000038016e00ec010004ec00000038016e00ec002613da00
0000263fec0226345c0026015c0c9201da0026540094ec00000038016e00ec010004ec00
000038016e00ec002614ec005c784a00920eec0026550094ec00000038016e00ec010004
ec00000038016e00ec002615da00ec86da0026560094ec00000038016e00ec010004ec00
000038016e00ec0026f50094ec00000038016e00ec010001ec000001ec00000038016e00
ec0026f50094ec00000038016e00ec010001ec000001ec00000038016e00ec0026f50094
ec00000038016e00ec010001ec000001ec00000038016e00ec0026f50094ec0000003801
6e00ec010001ec000001ec00000038016e00ec0026f50094ec00000038016e00ec010001
ec000001ec00000038016e00ec0026f50094ec00000038016e00ec010004ec0000003801
6e00ec0026f50094ec00000038016e00ec010004ec00000038016e00ec0026f50094ec00
000038016e00ec010004ec00000038016e00ec002615da00ec86da0026560094ec000000
38016e00ec010004ec00000038016e00ec002614ec000077260f4a00ec0026550015ec5d
0020ec00000038016e00ec010004ec00000038016e00ec002613da00000026775c002600
000d26005c00da0026540015ec00005bec000020ec00000038016e00ec010004ec000000
38016e00ec002613ec00000026775c0026000000260c5c009200ec0026540015ec00005b
ec000020ec00000038016e00ec010001ec000001ec00000038016e00ec002613ec000000
26775c00260000002605ec0026055c009200ec0026540015ec00005bec01001fec000000
38016e00ec010001ec000001ec00000038016e00ec002613ec0000002603ec002604ec00
2606ec00260aec022609ec002601ec00260dec042606ec00262d5c00260000002604ec02
26045c009200ec0026540015ec00005bec01001fec00000038016e00ec010001ec000001
ec00000038016e00ec002613ec0000002603ec012602ec012606ec002609ec002602ec00
2608ec002612ec002608ec00262d5c00260000002603ec0426035c009200ec0026540015
ec00005bec01001fec00000038016e00ec010001ec000001ec00000038016e00ec002613
ec0000002603ec002600ec002600ec002600ec002601ec012601ec022601ec022603ec00
2605ec012602ec022601ec002600ec022602ec022605ec002603ec012602ec00262d5c00
26000000260c5c009200ec0026540015ec000002ec010003ec010007ec01000cec03000a
ec010001ec010010ec050007ec010003ec01001fec00000038016e00ec010001ec000001
ec00000038016e00ec002613ec0000002603ec002601ec002601ec002603ec002601ec00
2601ec002606ec002604ec002601ec002600ec002601ec002601ec002600ec002601ec00
2600ec002601ec002605ec002602ec002601ec002601ec00262d5c0026000000260c5c00
9200ec0026540015ec000002ec020001ec020007ec01000bec010001ec010009ec010016
ec010009ec010003ec01001fec00000038016e00ec010004ec00000038016e00ec002613
ec0000002603ec002604ec002601ec022601ec002602ec012604ec002604ec002601ec00
2600ec002601ec002601ec002600ec002601ec002600ec002601ec002605ec002602ec00
2604ec00262d5c00260000002603ec0426035c009200ec0026540015ec000002ec070001
ec020001ec030001ec030004ec010005ec020002ec030001ec010000ec030002ec030006
ec010003ec020002ec010003ec01001fec00000038016e00ec010004ec00000038016e00
ec002613ec0000002603ec002604ec002600ec002601ec002601ec002604ec002603ec00
2602ec002600ec002601ec002600ec002601ec002601ec002600ec002601ec002600ec00
2601ec002605ec002602ec002601ec002601ec00262d5c00260000002604ec0226045c00
9200ec0026540015ec000002ec010000ec010000ec010003ec010001ec010001ec010007
ec010004ec010000ec010000ec010000ec010001ec010000ec010000ec010000ec010000
ec010006ec010002ec010000ec010001ec010003ec01001fec00000038016e00ec010004
ec00000038016e00ec002613ec0000002603ec002604ec002601ec022602ec002600ec02
2605ec022602ec012602ec022601ec002600ec002601ec002601ec022605ec002603ec01
2602ec00262d5c00260000002605ec0026055c009200ec0026540015ec000002ec010003
ec010001ec030001ec010002ec020005ec010004ec010000ec010000ec010000ec010001
ec010000ec010000ec010000ec010000ec010006ec010002ec010004ec010003ec01001f
ec00000038016e00ec010004ec00000038016e00ec002613ec0000002637ec00263e5c00
26000000260c5c009200ec0026540015ec000002ec010003ec010000ec010000ec010001
ec010004ec010004ec010001ec010000ec010000ec010000ec010000ec010001ec010000
ec010000ec010000ec010000ec010006ec010002ec010000ec010001ec010003ec01001f
ec00000038016e00ec010004ec00000038016e00ec002613da0000002635ec01263f5c00
26015c0c9201da0026540015ec000002ec010003ec010001ec030002ec010000ec030006
ec030002ec020002ec030001ec010000ec010000ec010001ec030006ec010003ec020002
ec010003ec01001fec00000038016e00ec010004ec00000038016e00ec002614ec005c78
4a00920eec0026550015ec000040ec010018ec01001fec00000038016e00ec010001ec00
0001ec00000038016e00ec002615da00ec86da0026560015ec00003eec020019ec01001f
ec00000038016e00ec010004ec00000038016e00ec0026f50015ec00005bec01001fec00
000038016e00ec010004ec00000038016e00ec0026f50015ec00005bec01001fec000000
38016e00ec010004ec00000038016e00ec0026f50015ec5e001fec00000038016e00ec01
0004ec00000038016e00ec0026f50018ec5b001fec00000038016e00ec010001ec000001
ec00000038016e00ec0026f50094ec00000038016e00ec010004ec00000038016e00ec00
26f50094ec00000038016e00ec010004ec00000038016e00ec0026f50094ec0000003801
6e00ec010004ec00000038016e00ec0026f50094ec00000038016e00ec010004ec000000
38016e00ec002615da00ecc7da0026150094ec00000038016e00ec020003ec0000003801
6e00ec002614ec0000b526124a00ec0026140094ec00000038016e00ec020003ec000000
38016e00ec002613da00000026b55c002600001026005c00da0026130094ec0000003801
6e00ec020000ec000001ec00000038016e00ec002613ec00000026b55c0026000000260f
5c009200ec0026130094ec00000038016e00ec020003ec00000038016e00ec002613ec00
0000260bec0d260eec00260cec032601ec002618ec022604ec0226535c0026000000260f
5c009200ec0026130094ec00000038016e00ec020003ec00000038016e00ec002613ec00
0000260aec012603ec012603ec01260dec01260aec012603ec022617ec002601ec012602
ec002601ec0126535c0026000000260f5c009200ec0026130094ec00000038016e00ec02
0003ec00000038016e00ec002613ec000000260aec002604ec012604ec00260cec022609
ec012605ec012616ec012602ec002601ec012602ec0026535c0026000000260f5c009200
ec0026130094ec00000038016e00ec020000ec000001ec00000038016e00ec002613ec00
00002609ec002604ec012604ec00260dec012609ec012606ec002603ec002611ec012605
ec0126585c0026000000260f5c009200ec0026130094ec00000038016e00ec010004ec00
000038016e00ec002613ec000000260fec012613ec012609ec01260aec012611ec012605
ec0126585c0026000000260f5c009200ec0026130094ec00000038016e00ec010004ec00
000038016e00ec002613ec000000260eec01260aec042603ec01260aec012608ec052600
ec032601ec032601ec052601ec0526575c00260000002606ec0026075c009200ec002613
0094ec00000038016e00ec010004ec00000038016e00ec002613ec000000260eec012608
ec022601ec022602ec01260aec032607ec012605ec012603ec012603ec012605ec012659
5c00260000002605ec0226065c009200ec0026130094ec00000038016e00ec010004ec00
000038016e00ec002613ec000000260dec012608ec012603ec012602ec01260cec032605
ec012605ec012603ec012603ec012605ec01265a5c00260000002604ec0426055c009200
ec0026130094ec00000038016e00ec010004ec00000038016e00ec002613ec000000260d
ec012607ec012609ec01260eec032603ec012605ec012603ec012603ec012605ec01265a
5c00260000002603ec0626045c009200ec0026130094ec00000038016e00ec010004ec00
000038016e00ec002613ec000000260cec012607ec012609ec012610ec022602ec012605
ec012603ec012603ec012605ec01265b5c0026000000260f5c009200ec0026130094ec00
000038016e00ec010004ec00000038016e00ec002613ec000000260cec012607ec012609
ec012611ec022601ec012605ec012603ec012603ec012605ec01265b5c0026000000260f
5c009200ec0026130094ec00000038016e00ec010001ec000001ec00000038016e00ec00
2613ec000000260bec012607ec012609ec012609ec002607ec012601ec012605ec012603
ec012603ec012605ec01265c5c00260000002603ec0626045c009200ec0026130094ec00
000038016e00ec010001ec000001ec00000038016e00ec002613ec000000260bec012607
ec012605ec002602ec012609ec002607ec012601ec012605ec012603ec012603ec012605
ec01265c5c00260000002604ec0426055c009200ec0026130094ec00000038016e00ec01
0001ec000001ec00000038016e00ec002613ec000000260aec012608ec012603ec012602
ec012609ec012606ec012601ec012602ec002601ec022602ec012603ec012605ec01265d
5c00260000002605ec0226065c009200ec0026130094ec00000038016e00ec010004ec00
000038016e00ec002613ec000000260aec012608ec062603ec012609ec022604ec012602
ec042603ec072602ec012605ec01265d5c00260000002606ec0026075c009200ec002613
0094ec00000038016e00ec010004ec00000038016e00ec002613ec0000002607ec052608
ec022603ec052607ec002601ec042605ec022605ec022600ec002602ec052601ec05265c
5c0026000000260f5c009200ec0026130015ec4e002fec00000038016e00ec010004ec00
000038016e00ec002613ec00000026b55c0026000000260f5c009200ec0026130015ec00
004cec00002fec00000038016e00ec010004ec00000038016e00ec002613ec00000026b5
5c0026000000260f5c009200ec0026130015ec00004cec00002fec00000038016e00ec01
0004ec00000038016e00ec002613ec00000026b55c0026000000260f5c009200ec002613
0015ec00004cec01002eec00000038016e00ec010004ec00000038016e00ec002613ec00
000026b55c0026000000260f5c009200ec0026130015ec00004cec01002eec0000003801
6e00ec010004ec00000038016e00ec002613ec00000026b55c0026000000260f5c009200
ec0026130015ec00004cec01002eec00000038016e00ec010004ec00000038016e00ec00
2613da00000026b55c0026015c0f9201da0026130015ec000002ec000004ec000006ec00
000aec020009ec000001ec00000dec040006ec000003ec01002eec00000038016e00ec02
0003ec00000038016e00ec002614ec005cb64a009211ec0026140015ec000002ec010002
ec010006ec000009ec000002ec000008ec000012ec000008ec000003ec01002eec000000
38016e00ec020003ec00000038016e00ec002615da00ecc7da0026150015ec000002ec00
0000ec000000ec000000ec000001ec010001ec020001ec020003ec000005ec010002ec02
0001ec000000ec020002ec020005ec000003ec010002ec000003ec01002eec0000003801
6e00ec020003ec00000038016e00ec0026f50015ec000002ec000001ec000001ec000003
ec000001ec000001ec000006ec000004ec000001ec000000ec000001ec000001ec000000
ec000001ec000000ec000001ec000005ec000002ec000001ec000001ec000003ec01002e
ec00000038016e00ec020003ec00000038016e00ec0026f50015ec000002ec000004ec00
0001ec020001ec000002ec010004ec000004ec000001ec000000ec000001ec000001ec00
0000ec000001ec000000ec000001ec000005ec000002ec000004ec000003ec01002eec00
000038016e00ec010004ec00000038016e00ec0026f50015ec000002ec000004ec000000
ec000001ec000001ec000004ec000003ec000002ec000000ec000001ec000000ec000001
ec000001ec000000ec000001ec000000ec000001ec000005ec000002ec000001ec000001
ec000003ec01002eec00000038016e00ec010004ec00000038016e00ec0026f50015ec00
0002ec000004ec000001ec020002ec000000ec020005ec020002ec010002ec020001ec00
0000ec000001ec000001ec020005ec000003ec010002ec000003ec01002eec0000003801
6e00ec010004ec00000038016e00ec0026f50015ec000036ec000014ec01002eec000000
38016e00ec010004ec00000038016e00ec0026f50015ec000034ec010015ec01002eec00
000038016e00ec010004ec00000038016e00ec0026f50015ec00004cec01002eec000000
38016e00ec010004ec00000038016e00ec0026f50015ec00004cec01002eec0000003801
6e00ec010004ec00000038016e00ec002615da00ec7eda00265e0015ec4f002eec000000
38016e00ec020003ec00000038016e00ec002614ec00b66ca400c812ec00265d0018ec4c
002eec00000038016e00ec020003ec00000038016e00ec002613da00b601a46b9200c800
b610a4008000da00265c0094ec00000038016e00ec020003ec00000038016e00ec002613
ec00b600a46c9200c800b600a40f92008000ec00265c0094ec00000038016e00ec020003
ec00000038016e00ec002613ec00b600a46c9200c800b600a40f92008000ec00265c0094
ec00000038016e00ec010004ec00000038016e00ec002613ec00b600a46c9200c800b600
a40f92008000ec00265c0094ec00000038016e00ec010004ec00000038016e00ec002613
ec00b600a46c9200c800b600a40f92008000ec00265c0094ec00000038016e00ec010004
ec00000038016e00ec002613ec00b600a46c9200c800b600a40f92008000ec00265c0094
ec00000038016e00ec010004ec00000038016e00ec002613ec00b600a46c9200c800b600
a40f92008000ec00265c0094ec00000038016e00ec010004ec00000038016e00ec002613
ec00b600a46c9200c800b600a40f92008000ec00265c0094ec00000038016e00ec010004
ec00000038016e00ec002613ec00b600a46c9200c800b600a40f92008000ec00265c0094
ec00000038016e00ec010004ec00000038016e00ec002613ec00b600a46c9200c800b600
a40f92008000ec00265c0094ec00000038016e00ec020000ec000001ec00000038016e00
ec002613ec00b600a4030005a4070001a4050003a4020000a40b0002a4000002a4379200
c800b600a4060000a40792008000ec00265c0094ec00000038016e00ec020000ec000001
ec00000038016e00ec002613ec00b600a4050001a4090001a4040001a4040001a40a0001
a4010001a4399200c800b600a4050002a40692008000ec00265c0094ec00000038016e00
ec020000ec000001ec00000038016e00ec002613ec00b600a4050001a4030003a4010001
a4040001a4030004a4000001a4010001a4000007a4389200c800b600a4040004a4059200
8000ec00265c0094ec00000038016e00ec020003ec00000038016e00ec002613ec00b600
a4050001a4020001a4010000a4010001a4040002a4030001a4020001a4010001a4010001
a4010001a4399200c800b600a4030006a40492008000ec00265c0094ec00000038016e00
ec010004ec00000038016e00ec002613ec00b600a4050001a4020001a4040001a4050002
a4020001a4020001a4010001a4010001a4010001a4399200c800b600a40f92008000ec00
265c0094ec00000038016e00ec010004ec00000038016e00ec002613ec00b600a4050001
a4020001a4040001a4060002a4010001a4020001a4010001a4010001a4010001a4399200
c800b600a40f92008000ec00265c0094ec00000038016e00ec010004ec00000038016e00
ec002613ec00b600a4050001a4020001a4040001a4070001a4010001a4020001a4010001
a4010001a4010001a4399200c800b600a4030006a40492008000ec00265c0094ec000000
38016e00ec010004ec00000038016e00ec002613ec00b600a4050001a4020001a4040001
a4070001a4010001a4020001a4000002a4010001a4010001a4399200c800b600a4040004
a40592008000ec00265c0094ec00000038016e00ec020003ec00000038016e00ec002613
ec00b600a4050001a4030003a4010001a4040003a4030002a4010001a4000001a4010001
a4010001a4399200c800b600a4050002a40692008000ec00265c0094ec00000038016e00
ec020003ec00000038016e00ec002613ec00b600a46c9200c800b600a4060000a4079200
8000ec00265c0094ec00000038016e00ec020003ec00000038016e00ec002613ec00b600
a46c9200c800b600a40f92008000ec00265c0094ec00000038016e00ec010004ec000000
38016e00ec002613ec00b600a46c9200c800b600a40f92008000ec00265c0094ec000000
38016e00ec010004ec00000038016e00ec002613ec00b600a46c9200c800b600a40f9200
8000ec00265c0094ec00000038016e00ec010004ec00000038016e00ec002613ec00b600
a46c9200c800b600a40f92008000ec00265c0015ec5e001fec00000038016e00ec010004
ec00000038016e00ec002613ec00b600a46c9200c800b600a40f92008000ec00265c0015
ec00005cec00001fec00000038016e00ec010004ec00000038016e00ec002613ec00b600
a46c9200c800b600a4070001a40592008000ec00265c0015ec00005cec00001fec000000
38016e00ec010004ec00000038016e00ec002613ec00b600a46c9200c800b600a4070000
ec000000a40492008000ec00265c0015ec00005cec01001eec00000038016e00ec010004
ec00000038016e00ec002613ec00b600a46c9200c800b600a4070000ec010000a4039200
8000ec00265c0015ec00005cec01001eec00000038016e00ec010004ec00000038016e00
ec002613ec00b600a46c9200c800b600a4070000ec020000a40292008000ec00265c0015
ec00000aec0d000eec00000cec030001ec000018ec020003ec02001dec00000038016e00
ec010004ec00000038016e00ec002613da00b600a46c9200c800a40092070000ec030000
92018001da00265c0015ec000009ec010003ec010003ec01000dec01000aec010003ec02
0017ec000001ec010002ec03001dec00000038016e00ec010004ec00000038016e00ec00
2614ec00926dc80080080000ec0400008001ec00265d0015ec000009ec000004ec010004
ec00000cec020009ec010005ec010016ec010002ec000001ec03001eec00000038016e00
ec010004ec00000038016e00ec002615da00ec760000ec050000da00265e0015ec000008
ec000004ec010004ec00000dec010009ec010006ec000003ec000011ec010005ec010000
ec01001eec00000038016e00ec010004ec00000038016e00ec00268d0000ec060000265e
0015ec00000eec010013ec010009ec01000aec010011ec010005ec010000ec01001eec00
000038016e00ec010004ec00000038016e00ec00268d0000ec070000265d0015ec00000d
ec01000aec040003ec01000aec010008ec050000ec030001ec030001ec050001ec07001e
ec00000038016e00ec010004ec00000038016e00ec00268d0000ec040004265c0015ec00
000dec010008ec020001ec020002ec01000aec030007ec010005ec010003ec010003ec01
0005ec010001ec01001eec00000038016e00ec010004ec00000038016e00ec00268d0000
ec010000ec01000026600015ec00000cec010008ec010003ec010002ec01000cec030005
ec010005ec010003ec010003ec010005ec010002ec01001eec00000038016e00ec010004
ec00000038016e00ec00268d0000ec00000026000000ec010000265f0015ec00000cec01
0007ec010009ec01000eec030003ec010005ec010003ec010003ec010005ec010002ec01
001eec00000038016e00ec010004ec00000038016e00ec00268d000126010000ec010000
265f0015ec00000bec010007ec010009ec010010ec020002ec010005ec010003ec010003
ec010005ec010003ec01001eec00000038016e00ec010004ec00000038016e00ec00268d
000026030000ec010000265e0015ec00000bec010007ec010009ec010011ec020001ec01
0005ec010003ec010003ec010005ec010003ec01001eec00000038016e00ec010004ec00
000038016e00ec0026920000ec010000265e0015ec00000aec010007ec010009ec010009
ec000007ec010001ec010005ec010003ec010003ec010005ec010004ec01001eec000000
38016e00ec010004ec00000038016e00ec0026930002265e0015ec00000aec010007ec01
0005ec000002ec010009ec000007ec010001ec010005ec010003ec010003ec010005ec01
0004ec01001eec00000038016e00ec010004ec00000038016e00ec0026f50015ec000009
ec010008ec010003ec010002ec010009ec010006ec010001ec010002ec000001ec020002
ec010003ec010005ec010005ec01001eec00000038016e00ec010004ec00000038016e00
ec0026f50015ec000009ec010008ec060003ec010009ec020004ec010002ec040003ec07
0002ec010005ec010005ec01001eec00000038016e00ec010004ec00000038016e00ec00
26f50015ec000006ec050008ec020003ec050007ec000001ec040005ec020005ec020000
ec000002ec050001ec050004ec01001eec00000038016e00ec010004ec00000038016e00
ec0026f50015ec00005cec01001eec00000038016e00ec010004ec00000038016e00ec00
26f50015ec00005cec01001eec00000038016e00ec010004ec00000038016e00ec0026f5
0015ec00005cec01001eec00000038016e00ec010004ec00000038016e00ec0026f50015
ec00005cec01001eec00000038016e00ec010004ec00000038016e00ec0026f50015ec00
005cec01001eec00000038016e00ec010004ec00000038016e00ec0026f50015ec00005c
ec01001eec00000038016e00ec010004ec00000038016e00ec0026f50015ec00005cec01
001eec00000038016e00ec010004ec00000038016e00ec0026f50015ec00005cec01001e
ec00000038016e00ec010004ec00000038016e00ec0026f50015ec5f001eec0000003801
6e00ec010004ec00000038016e00ec0026f50018ec5c001eec00000038016e00ec010004
ec00000038016e00ec0026f50094ec00000038016e00ec010004ec00000038016e00ec00
26f50094ec00000038016e00ec010004ec00000038016e00ec0026f50094ec0000003801
6e00ec020003ec00000038016e00ec0026f50094ec00000038016e00ec020003ec000000
38016e00ec0026f50094ec00000038016e00ec010004ec00000038016e00ec0026f50094
ec00000038016e00ec010004ec00000038016e00ec0026f50094ec00000038016e00ec01
0004ec00000038016e00ec0026f50094ec00000038016e00ec010004ec00000038016e00
ec0026f50094ec00000038016e00ec010004ec00000038016e00ec0026f50094ec000000
38016e00ec010004ec00000038016e00ec0026f50094ec00000038016e00ec010004ec00
000038016e00ec0026f50094ec00000038016e00ec010004ec00000038016e00ec0026f5
0094ec00000038016e00ec010004ec00000038016e00ec0026f50094ec00000038016e00
ec010004ec00000038016e00ec0026f50094ec00000038016e00ec010004ec0000003801
6e00ec0026f50094ec00000038016e00ec010004ec00000038016e00ec0026f50094ec00
000038016e00ec010004ec00000038016e00ec0026f50094ec00000038016e00ec010004
ec00000038016e00ec0026f50094ec00000038016e00ec010004ec00000038016e00ec00
26f50094ec00000038016e00ec010004ec00000038016e00ec0026f50094ec0000003801
6e00ec010004ec00000038016e00ec0026f50094ec00000038016e00ec010004ec000000
38016e00ec0026f50094ec00000038016e00ec010004ec00000038016e00ec0026f50015
ec570026ec00000038016e00ec010004ec00000038016e00ec0026f50015ec000055ec00
0026ec00000038016e00ec010004ec00000038016e00ec0026f50015ec000055ec000026
ec00000038016e00ec010004ec00000038016e00ec0026f50015ec000055ec010025ec00
000038016e00ec010004ec00000038016e00ec0026f50015ec000055ec010025ec000000
38016e00ec010004ec00000038016e00ec0026f50015ec000055ec010025ec0000003801
6e00ec010004ec00000038016e00ec0026f50015ec000055ec010025ec00000038016e00
ec010004ec00000038016e00ec0026f50015ec000055ec010025ec00000038016e00ec01
0004ec00000038016e00ec0026f50015ec000055ec010025ec00000038016e00ec010004
ec00000038016e00ec0026f50015ec000055ec010025ec00000038016e00ec010004ec00
000038016e00ec0026f50015ec000055ec010025ec00000038016e00ec010004ec000000
38016e00ec0026f50015ec000055ec010025ec00000038016e00ec010004ec0000003801
6e00ec0026f50015ec000055ec010025ec00000038016e00ec010004ec00000038016e00
ec0026f50015ec000012ec050007ec010005ec030002ec00000bec020000ec020011ec01
0025ec00000038016e00ec010004ec00000038016e00ec0026f50015ec000014ec010009
ec010004ec010004ec01000aec010001ec010013ec010025ec00000038016e00ec010004
ec00000038016e00ec0026f50015ec000014ec010003ec030001ec010004ec010003ec04
0000ec010001ec010000ec070012ec010025ec00000038016e00ec010004ec0000003801
6e00ec0026f50015ec000014ec010002ec010001ec000001ec010004ec020003ec010002
ec010001ec010001ec010001ec010013ec010025ec00000038016e00ec010004ec000000
38016e00ec0026f50015ec000014ec010002ec010004ec010005ec020002ec010002ec01
0001ec010001ec010001ec010013ec010025ec00000038016e00ec010004ec0000003801
6e00ec0026f50015ec000014ec010002ec010004ec010006ec020001ec010002ec010001
ec010001ec010001ec010013ec010025ec00000038016e00ec010004ec00000038016e00
ec0026f50015ec000014ec010002ec010004ec010007ec010001ec010002ec010001ec01
0001ec010001ec010013ec010025ec00000038016e00ec010004ec00000038016e00ec00
26f50015ec000014ec010002ec010004ec010007ec010001ec010002ec010000ec020001
ec010001ec010013ec010025ec00000038016e00ec010004ec00000038016e00ec0026f5
0015ec000014ec010003ec030001ec010004ec030003ec020001ec010000ec010001ec01
0001ec010013ec010025ec00000038016e00ec010004ec00000038016e00ec0026f50015
ec000055ec010025ec00000038016e00ec010004ec00000038016e00ec0026f50015ec00
0055ec010025ec00000038016e00ec010004ec00000038016e00ec0026f50015ec000055
ec010025ec00000038016e00ec010004ec00000038016e00ec0026f50015ec000055ec01
0025ec00000038016e00ec010004ec00000038016e00ec0026f50015ec000055ec010025
ec00000038016e00ec010004ec00000038016e00ec0026f50015ec000055ec010025ec00
000038016e00ec010004ec00000038016e00ec0026f50015ec000055ec010025ec000000
38016e00ec010004ec00000038016e00ec0026f50015ec000055ec010025ec0000003801
6e00ec010004ec00000038016e00ec0026f50015ec000055ec010025ec00000038016e00
ec010004ec00000038016e00ec0026f50015ec000055ec010025ec00000038016e00ec01
0004ec00000038016e00ec0026f50015ec000055ec010016ec0f000038016e00ec010004
ec00000038016e00ec0026f50015ec000055ec010016ec00000f38016e00ec010004ec00
000038016e00ec0026f50015ec580016ec00000038106e00ec010004ec00000038016e00
ec0026f50018ec550016ec00000038106e00ec010004ec00000038016e00ec0026f50085
ec0000003806000138076e00ec010004ec00000038016e00ec0026f50085ec0000003805
00003800920038076e00ec010004ec00000038016e00ec0026f50085ec00000038040000
380092003800000138056e00ec010004ec00000038016e00ec0026f50085ec0000003803
000038009200380000003800920038056e00ec010004ec00000038016e00ec0026f50085
ec000000380200003800920038000000380092003800000138036e00ec010004ec000000
38016e00ec0026f50085ec00000038010000380092003800000038009200380000003800
920038036e00ec010004ec00000038016e00ec0026f50085ec00000038015c0092003800
000038009200380000003800920038046e00ec010004ec00000038016e00ec0026f50085
ec0000003803000038009200380000003800920038056e00ec010004ec00000038016e00
ec0026f50085ec00000038035c009200380000003800920038066e00ec010004ec000000
38016e00ec0026f50085ec000000380500003800920038076e00ec010004ec0000003801
6e00ec0026f50085ec00000038055c00920038086e00ec010004ec00000038016e00ecff
ec7d000038106e00ec010004ec000000380200ff007e38106e00ec010004ec00000038ff
38926e00ec010004ec00000038ff38926e00ec010004ec0038006eff6e93ec010004ecff
ec970006ecffec9500ff0042b6002612b60100ff0086b6002612b6010046
%%EndData
end
%%PageTrailer
%%Trailer
%%EOF
Deleted tip/51compare.gif.

cannot compute difference between binary files

Deleted tip/51compare.txt.
1
2
3
4
5
6
7







-
-
-
-
-
-
-
,-------------------------------.
|				|
| Please see version on website	|
| for this image, as it doesn't	|
| represent well in plain text.	|
|				|
`-------------------------------'
Deleted tip/52.tip.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
















































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TIP:		52
Title:		Hierarchical Namespace Lookup of Commands and Variables
Version:	$Revision: 1.1 $
Author:		David Cuthbert <[email protected]>
State:		Draft
Type:		Project
Vote:		Pending
Created:	09-Aug-2001
Tcl-Version:	8.4
Post-History:   
Discussions-To:	news:comp.lang.tcl
Keywords:	namespace,lookup,hierarchy

~ Abstract

This TIP proposes to change the command and variable namespace lookup
system so that the full hierarchy of namespaces is parsed, rather than
just the current namespace followed by the global namespace.  This is
primarily intended to rectify problems often encountered with the use
of [[incr Tcl]] (ITcl) and namespaces.  In addition, package
encapsulation can be enhanced with judicious application of this
feature.

~ Rationale

Currently, the following code is invalid in Tcl/ITcl:

|package require Itcl
|
|namespace eval SampleNS {
|    proc Hello {} { puts "Hello world!" }
|
|    ::itcl::class X {
|        public constructor {} {} { Hello }
|    }
|}
|
|SampleNS::X x1  ;# Error: invalid command name "Hello"

This is due to the fact that ITcl classes double as namespaces.
Therefore, the lookup of ''Hello'' takes place first in
''::SampleNS::X'', followed by ''::'' (the global namespace).

The current workaround - to reopen the class' namespace and issue a
''namespace import'' directive - is of limited value since ''namespace
import'' is not capable of bringing in names defined later on.  The
following code illustrates this point:

|package require Itcl
|
|namespace eval SampleNS {
|    ::itcl::class X1 {
|        public method GetSibling {} { return [X2 \#auto] }
|    }
|    namespace eval X1 { namespace import ::SampleNS }
|
|    # Further down, or perhaps in a separate file source later:
|
|    ::itcl::class X2 { }
|}
|
|set x [SampleNS::X1 \#auto]
|$x GetSibling ;# Error: invalid command name "X2"

Non-ITcl code can also make use of hierarchical namespaces to better
encapsulate support procedures.  In this example, the child namespace
''private'' illustrates that the ''GetUniqueId'' procedure should not
be used outside of the package; however, ''GetUniqueId'' still has
access to the procedures and variables in the package's main
namespace:

|# MyPackage
|
|namespace eval MyPackage {
|    variable nextId 0
|
|    namespace eval private {
|        proc GetUniqueId {} {
|            variable nextId
|            return "MyPackage.[incr nextId]"
|        }
|    }
|
|    proc CreateObject {} {
|        set name ::[private::GetUniqueId]
|        proc $name args { body }
|        return $name
|    }
|}


~ Specification

Currently, the ''NAME RESOLUTION'' section of the ''namespace''
documentation states:

 > If the name does not start with a :: (i.e., is ''relative''), Tcl
   follows a fixed rule for looking it up: Command and variable names
   are always resolved by looking first in the current namespace, and
   then in the global namespace.  Namespace names, on the other hand,
   are always resolved by looking in only the current namespace.

The proposed change to this is as follows:

 > If the name does not start with a :: (i.e., is ''relative''), Tcl
   follows a fixed rule for looking it up: Command and variable names
   are always resolved by traversing the namespace hierarchy - that
   is, the current namespace is examined first, followed by the
   parent, the parent's parent, and so on, until (finally) the global
   namespace is examined.  Namespace names, on the other hand, are
   always resolved by looking in only the current namespace.

By keeping the current behaviour for namespace names, this TIP affects
only completely unqualified commands and variables (i.e. those that do
not contain ::).  Changing the behaviour of partially qualified names
(those that are relative ''and'' contain ::) is often unintuitive and
can lead to unexpected errors.

~ Consequences

 1. ITcl classes and child namespaces can refer to command and
    variable names in their parent hierarchy without requiring the
    names to be fully qualified.  This improves the intuitiveness and
    readability of Tcl code.  In addition, it can reduce the
    brittleness of the code should parent namespace names undergo a
    change (e.g., ''namespace eval scriptics.com'' to ''namespace eval
    ajubasolutions.com'').

 2. Currently well-defined behaviour is modified.  This can break
    existing code if the following conditions are met:

 > * The code employs the use of namespaces with a depth greater than
     one below the global namespace.

 > * The code creates a variable or procedure in a parent namespace
     with the same name as a variable or procedure in the global
     namespace.

 > * The code in the child namespace uses unscoped names to refer to
     commands and/or variables in the global namespace.

 > A cursory examination of existing Tcl code available on the
   Internet revealed no code which used deeply nested namespaces.

 3. Existing well-defined behaviour of the internal Tcl function
    ''TclGetNamespaceForQualName'' is modified.  Under the sample
    implementation, the ''altNsPtrPtr'' parameter (which currently
    returns a pointer to the global namespace if a name was found
    there) always returns NULL.  It is up to the calling functions
    (e.g., Tcl_FindCommand and Tcl_FindNamespaceVar) to traverse the
    hierarchy.  Although the Tcl and Tk code-base can be modified to
    accommodate this, extensions which depend on this internal
    function may be broken.

~ Namespace History

Namespaces were originally developed by Michael McLennan for ITcl, and
apparently had this hierarchical resolution feature.  When they were
adopted into Tcl, an optimisation was made which led to the current
behaviour.

This TIP argues for the reversal of this decision based on experiences
with the new behaviour.

~ See Also

 * Tcl manual page ''namespace''.

 * Tcl source code file ''tcl8.4a3/generic/tclNamesp.c''.

 * Sample implementation at http://www.kanga.org/tclnamespace/

~ Copyright

Copyright � 2001 by David Cuthbert.  Distribution in whole or part,
with or without annotations, is unlimited.
Deleted tip/53.tip.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76












































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TIP:		53
Title:		Addition of 'assert' Command
Author: 	Gerald W. Lester <[email protected]>
Type:		Project
Vote:		Pending
State:		Draft
Created:	14-Aug-2001
Post-History:   
Tcl-Version:	8.4
Version:	$Revision: 1.1 $
Keywords:	bytecode,compiler

~ Abstract

This TIP proposes the addition of an ''assert'' command and supporting
infrastructure to the Tcl core.

~ Rationale

Many languages, including other scripting languages, have assertion
checking features that can be used to assist in validating program
correctness.  Typically, these assertion checking features can be
"compiled out" of production systems so as not to impact performance. 
To have a similar effect in Tcl, the assertion checking features must
be implemented at the byte code compiler level.

If, doing byte code compilation, an assert command is encountered the
byte code stream generated will be dependent on the value of the
''assert_enabled'' command line option.  If the option is true, a byte
code stream will be emitted to implement the assert command.  If the
option is not true, no byte code will be emitted.

Similarly, if the interpreter encounters an ''assert'' command (either
compiled or uncompiled), it will only execute it if the
''assert_enabled'' command line option is true.

It is acceptable for the compiler to throw an error if the
''booleanExpression'' is not brace quoted.

~ Tcl-Level Specification

The manual entry for the ''assert'' command is included here:

----

~NAME

 > assert - Assert a run time validation condition

~SYNOPSIS

|   assert booleanExpression messageText


~DESCRIPTION

 > This command has no effect if the assert_enabled command line
   option is not true at both compile and run time.  If the
   ''assert_enabled'' command line option is true at both compile and
   run time, the following behavior will occur:

 > 1. The ''booleanExpression'' will be evaluated

 > 2. If the ''booleanExpression'' evaluates to a true value,
      ''assert::failed'' will be called at the global level with
      ''messageText'' as its one and only parameter.

 > The default implementation of ''assert::failed'' will write
   ''messageText'' to standard out and ''exit'' with a status code of
   1.

----

~ Copyright

This TIP is in the public domain.
Deleted tip/54.tip.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226


































































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TIP:            54
Title:          Using PURLs to Unite the Tcl Webspace
Version:        $Revision: 1.5 $
Author:         Andreas Kupries <[email protected]>
State:          Draft
Type:           Process
Vote:           Pending
Created:        16-Aug-2001
Post-History:   

~ Abstract

This TIP proposes the use of PURLs to unify the scattered landscape of
Tcl URLs into a coherent set of information about the language, the
community, extensions, etc.

~ Background & Rationale

One of the recurring themes in the community in general (and
news:comp.lang.tcl in particular) is the lack of central website
people can turn to for an introduction to the language, the community,
search for extensions and packages, et cetera.

Most of the solutions proposed so far have the distinctive
disadvantage of not being able to use the existing sites and bind them
into a whole. This is further aggravated by the fact that the
'natural' domain names, like for example http://www.tcl.com/ and
http://www.tcl.org are already taken by other entities, commercial and
not, and thus not available anymore.

Instead of giving up at this point I propose to use PURLs a.k.a.
''Persistent URLs'' to construct a virtual website (the ''Tcl space'')
out of all the existing independent efforts. See http://www.purl.org/
for more explanations of PURLs.

Note that PURLs not only can refer to single URLs but to entire
sites. The latter is done through a technique called 'partial
redirection'. This ... is emphasized here because partially redirected
PURL have to be used with a trailing slash whereas PURLs referring to
single URL must not have a trailing slash.

In the lists below partially redirected PURLs are indicated by a
trailing slash.

A restriction we face is that PURLs are case insensitive. This means
that the names we will have to come up with have to be unique even
with case removed.

One of the most important features is the persistency. In real life
however organizations, people, websites, etc. can disappear. According
to http://www.purl.org/OCLC/PURL/FAQ#toc3.14 the PURL stays in
existence but can be redirected to a page detailing the history of the
purl. This would include the decommission. We could also do our own
scheme and redirect the purl to a page explaining the history in a
more Tcl-specific manner (like: Company went out of business, was
acquired, etc.).

~ Specification

This TIP is driven by several conflicting needs:

   * The names will be persistent, so give them some thought before
     creating them; they cannot be undone. This also implies that we
     to set up a simple and minimal structure first so as not to block
     future enhancements and flexibility.

   * Define the structure now before the URN space gets as scattered
     as the URL space is. Note that this process has already
     begun. The PURL resolver at http://www.purl.org/ currently has
     registered 24 Tcl-related PURLs which are not bound together in
     the framework proposed here. Action is necessary to prevent
     further confusion.

Of the existing PURLs the PURL domain ''/tcl'' created by Don Libes is
the most promising one for the unification of the Tcl space. Six of
the 24 aforementioned PURLs are defined below this domain too,
providing a (good) framework on which to build.

The existing PURLs and sub-domains in the ''/tcl'' domain are:

   * ''expect''	- reference to the homepage of the expect extension

   * ''faq''	- reference to the main FAQ

   * ''faqs''	- introduction to the available FAQ documents.

   * ''home/''	- refers to the Tcl Developers Xchange

   * ''tip/''	- refers to the TIP archives

   * ''wiki''	- refers to the entry page of the Tcl'ers WIKI

With the exception of ''expect'' all of these are general classes
and/or refer to important sites. They are used as is, except for
''expect'' which has to be redirected into the proposed sub-domain
''package''.

The following new sub-domains covering the most important general
classes of information and/or websites are proposed here. Please note
that the examples used in the list below are using purely informal
everyday names to refer to entities in the proposed domain. These
examples should not be seen as suggestions for the concrete naming
scheme used by the domain.

   * ''announce'' - Direct reference to a page explaining how to
     announce packages, applications and other tcl-related news and
     linking to the relevant newsgroups, mail archives and submission
     addresses. This includes, but is not restricted to:

   > * A link to the newsgroup ''comp.lang.tcl.announce''.

   > * A link to the eGroups/Yahoo archive of the c.l.t.a newsgroup.

   > * The submission address of c.l.t.a. to directly submit via email
       announcements.

   * ''newsletter'' - Direct reference to an archive of ''Tcl-URL!''.

   * ''package/'' - Sub-domain to contain references to the homepages
     of the known packages. This TIP makes no distinction between
     C-level extensions and script libraries. From the point of view
     of the core these are all packages to be required.

   > Examples of packages are ''Expect'', ''tcllib'', etc.

   * ''application/'' - Sub-domain to contain references to the
     homepages of applications related to Tcl, written in Tcl or using
     it internally.

   > Examples of applications are ''frink'', ''tclHttpd'',
     ''AOLServer'', etc.

   * ''person/'' - Sub-domain to contain references to the homepages of
     people active in the community, as far as they are interested in
     such a reference. References in this domain shall be personal and
     not organization-related. The latter will go into their own
     domain.

   > Examples of people are ''Larry Virden'', ''Cameron Laird'', etc.

   * ''org/'' - Sub-domain to contain references to organizations
     important to the Tcl community.

   > Examples are the Tcl Core Team, the Tcl Core Maintainers,
     Tcl-based based companies (PhaseIt, ActiveState), companies and
     organizations using Tcl (NIST, CAS), etc.

~ Management

The ''/tcl'' domain was created by Don Libes which made him
automatically the maintainer of the domain (see
http://www.purl.org/maint/search_user.pl.cgi?userid=^LIBES$). He has
already extended the maintainership to the entity TCLGROUP (see
http://www.purl.org/maint/search_group.pl.cgi?groupid=^TCLGROUP$),
currently consisting of

   * Gordon Johnstone <[email protected]>

   * Jeffrey Hobbs <[email protected]>

   * Don Libes <[email protected]>

   * Andreas Kupries <[email protected]>

   * Larry Virden <[email protected]>

   * Don G. Porter <[email protected]>

   * Jean-Claude Wippler <[email protected]>

For the future I propose that

   * High-level changes to the Tcl space, like new sub-domains, have to
     go through the TCT and the TIP process for approval. This is also
     in line with [0] declaring the responsibility of the TCT for the
     Tcl webspace.

   * The day-to-day routine of adding new packages, persons,
     organizations, etc. is delegated to a new group, the ''Tcl
     Namespace Maintainers''.

   > Initially this group would consist of the people mentioned above,
     with membership open to volunteers from the community.

~ Discussion

   * All of the newly proposed sub-domains will be simple listings
     mapping from the names of the entities contained in them to the
     proper locations. Further categorization of the entities by
     topic, gender or other attributes is out of the scope of this
     TIP. This type of categorization rather is in the domain of
     general and specialized catalogs which can be set up later and
     then bound into the unified webspace proposed here.

   > Note that such catalogs can and should make use of the proposed
     domains to reduce the effort necessary by them to stay current
     with respect to the location of the referenced entities (people,
     packages, etc).

   * The first pre-draft of this TIP contained definitions for the
     names to use in the various domains. These definitions have been
     removed on the grounds that their format and other issues like
     resolution of naming conflicts, order of precedence, etc. are
     best handled in one or more separate documents. The role of this
     TIP is to lay down a framework within which the community can
     operate and not to fill in every conceivable detail.

   > These details can be discussed and decided upon by the group of
     maintainers proposed in the last section.

   * This proposal makes the Tcl community dependent on an external
     entity, namely the maintainers of http://www.purl.org/. This is
     considered acceptable.

~ Example

The following examples show how to use PURLs, using some of the
already existing ones:

    * http://www.purl.org/tcl/tip/ refers to the TIP archive.

    * http://www.purl.org/tcl/wiki/ refers to the Tcl'ers Wiki.

~ Copyright

This document is in the public domain.
Deleted tip/55.tip.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206














































































































































































































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TIP:            55
Title:          Package Format for Tcl Extensions
Version:        $Revision: 1.1 $
Author:         Steve Cassidy <[email protected]>
State:          Draft
Type:           Project
Vote:           Pending
Created:        16-Aug-2001
Tcl-Version:	8.4
Post-History:   

~ Abstract

Defines the contents of a packaged Tcl extension suitable for
automated installation into an existing Tcl installation.

~ Rationale

There is currently no standard way of distributing or installing a Tcl
extension package.  The TEA document defines a standard interface to
''building'' extensions and includes an ''install'' target but
presumes that the extension is being installed on the same machine as
it was built. This TIP defines a directory structure for an extension
which can be packaged (as a zip or tar file) and transferred for
installation on another machine.

This TIP does not address the mechanism for the installation of these
packages and acknowledges that additional information may be required
in some cases to install a complex package. Rather than deal with all
of these issues at once, this TIP is intended to put forward a basic
package format which is workable for a significant proportion of Tcl
extensions.

~ References

Much of the required structure for an installable extension is defined
by the requirements of Tcl's existing package loading methods.  An
installable package structure should largely mirror that of an
installed package where possible.

The R system (a statistical package: http://www.r-project.org/) has a
well defined package format for extensions which enables automatic
installation of new extensions and integration of documentation and
demonstration programs for these extensions with that of the main R
system.

~ Requirements

The simplest case of a Tcl extension is one that contains only Tcl
code; I will consider these first and look at the additional issues
raised by compiled extensions later.

The minimum contents of a Tcl only extension are defined by the
requirements of [[package require xyzzy]].  The extensions needs to be
placed in a directory on the ''auto_path'' and must contain at least
''pkgIndex.tcl'' and one or more ''.tcl'' files which implement the
extension.

In addition to these files, it is useful to include documentation for
the commands implemented by the extension and some additional
meta-information about the package author etc.  Extensions might also
optionally include demonstration scripts illustrating their use, these
could either be incorporated into the documentation or included as
standalone Tcl files.

Extensions which include shared libraries add an additional layer of
complexity since these packages will only run on the platforms for
which the extension has been compiled.  There are two clear options
here: either packages are platform specific, intended for installation
on one platform alone, or the structure of the package is extended to
allow the option of including multiple shared libraries.  The latter
option would allow a single installation to serve multiple platforms
and so should be preferred.

~ Proposed Structure

The following directory structure is proposed for an installable
package: 

|  packagename  
|      + DESCRIPTION      -- Description of the package in "Field: value" format
|      + pkgIndex.tcl
|      + *.tcl            -- package source file(s)
|      + doc/             -- package documentation
|      + examples/        -- example scripts
|      + $platform/$os/   -- shared library directories

In addition, a package may include any additional files or directories
required for it's operation.

The formats of the required files is defined as follows.

''DESCRIPTION'' contains a number of records to provide
meta-information about this package. This should include at least the
fields illustrated in the following example:

|  Package: stemmer
|  Version: 1.0
|  Title: A stemmer for English.
|  Author: Steve Cassidy, SHLRC, Macquarie University
|  Email:  [email protected]
|  Description:   Provides a function to remove any prefixes or suffixes on
|	  a word to give the word stem. Uses Porter's algorithm to do this
|	  in an intelligent manner with an accuracy of around 80%. 
|  License: BSD 
|  URL: http://www.shlrc.mq.edu.au/emu/tcl/
|  Released: Thu Aug 16 22:29:08 EST 2001  

Fields are prefixed by the field name followed by a colon,
continuation lines begin with a tab character.

''pkgIndex.tcl'' is a normal Tcl package index file and may be either
hand written or automatically generated [[this could be made optional
since it could be automatically generated if not present in most
cases]].

''*.tcl'' are the Tcl source files implementing the package. There may
be zero or more of these and they may be stored in a subdirectory. The
''pkgIndex.tcl'' file should take care of sourcing these files as
required.

''doc/'' directory contains documentation in an accepted format.
Currently Tcl documentation is delivered either in source form (nroff
or TMML) or as HTML files.  Given the lack of a standard cross
platform solution, this TIP does not require a specific format;
however, the inclusion of either a text or HTML formatted help file is
strongly encouraged.

''examples/'' directory contains one or more Tcl files giving examples
of the use of this extension. These should be complete scripts
suitable for either sourcing in tclsh/wish or running from the command
line. The examples should be self contained and any external data
should be included in files in this directory or a sub-directory.

''$platform/$os'' directories contain shared libraries for various
platforms. ''$platform'' refers to the Tcl variable
''$tcl_platform(platform)'', ''$os'' refers to the Tcl variable
''$tcl_platform(os)''.  The package need not provide all possible
combinations of platform and OS and may only provide one shared
library.  This structure is proposed to allow shared libraries to
co-exist in a multi-platform environment and to allow binary
extensions to be distributed in multi-platform packages.  The
platform/OS pairs included in the package should be referenced in the
DESCRIPTION file, for example:

|   Platform: i686/Linux i686/Windows 

~ Alternatives

Alternatives might be considered for the package DESCRIPTION file, for
the documentation directory and for the location of shared libraries.

An alternative for package DESCRIPTION file is to include a more
general package description, for example the XML based ``ppd'' format
used to describe Perl packages on the ActiveState Perl extension
repository. The main motivation for the simple format proposed is that
it is trivial for authors to write and trivial for programs to read.
The reason for preferring an XML based alternative would have to be to
take advantage of existing standards (e.g. ppd) and existing tools
associated with those standards.  I am not aware of any extensive
tool-set which would make any XML format preferable for this
application.  I note that the ppd format could still be used to
describe packages stored in a repository for installation and that
some of the information required to build the ppd format could be
derived from the DESCRIPTION file.

In the R package format referenced earlier, documentation is included
in a standard source form and is converted to HTML or text based help
pages; these might be included in the package or derived from the
source forms on installation. The closest option for Tcl would be to
require nroff format help files which can be converted to HTML or text
files on installation.  Unfortunately there is no guaranteed tool to
do nroff->X conversion on Windows or Macintosh platforms.  Until there
is an accepted way of authoring Tcl documentation this TIP defers any
standard layout of these files in an installable package.

The alternative to having shared libraries in specific directories is
to have separate packages for each new platform. This has the
advantage of making the packages smaller and more closely correspond
to the existing directory structure of an installed extension.  The
main motivation for the suggested directory structure is to allow
multi-platform packages or to facilitate multi-platform installations.


~ Supporting Tools

The standards outlined in this TIP should be supported by Tcl scripts
to:

 * Generate empty package templates for new projects.

 * Validate package directories or archive files.

 * Read and write the DESCRIPTION file and provide a standard
   interface to the information it contains.

 * Install an extension from an appropriately structured archive.

In addition, the TEA standard should be extended with a ''package''
makefile target which will act like the current ''install'' target but
which will copy files to a local directory and optionally build an
archive of the package for distribution.

~ Copyright  

This document has been placed in the public domain.
Changes to tip/6.tip.
1
2
3
4
5
6
7
8
9










10
11
12
13
14
15
16
17
18
19
20
21
22



23
24
25

26
27

28
29

30
31
32
33
34
35
36
37









1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
18
19



20
21
22
23


24


25


26

27
28
29
30
31
32
33
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-









-
-
-
+
+
+

-
-
+
-
-
+
-
-
+
-







TIP:            6
Title:          Include [Incr Tcl] in the Core Tcl distribution
Version:        $Revision: 1.5 $
Author:         Mark Harrison <[email protected]>
State:          Rejected
Type:           Project
Vote:           Done
Created:        16-Oct-2000
Post-History:   
TIP:           6
Title:         Include [Incr Tcl] in the Core Tcl distribution
Version:       $Revision: 1.2 $
Author:        Mark Harrison <[email protected]>
State:         Draft
Type:          Project
Tcl-Version:   8.4.0
Vote:          Pending
Created:       16-Oct-2000
Post-History:
Tcl-Version:    8.4.0

~ Abstract

Include [[Incr Tcl]] in the Core Tcl distribution.

~ Proposal

[[incr Tcl]] (http://tcltk.com/itcl/) shall be included in the core
Tcl distribution.  It shall be included in the Tcl source tree, and
built as part of the standard Tcl distribution.

Specific items:
built as part of the standard Tcl distribution.  It shall remain a
dynamically loaded extension, accessible via "package require" and
"namespace import".

 *  "itclsh" will not be included

Specifically not included are "itclsh" and the obsolete "itcl_*"
 *  "itcl_*" commands will not be included

commands.  These can be provided in an independent itcl compatibility
 *  everything will move from ::itcl to ::

package for those that need it.
 *  the "find" subcommands will be reintegrated into "info"

~ Rationale

The lack of a standard object and data abstraction system continues to
hinder Tcl development.

  > "Lets face it, not including any sort of OO system is one of
Changes to tip/8.tip.
1
2
3

4
5
6
7
8
9
10
1
2

3
4
5
6
7
8
9
10


-
+







TIP:           8
Title:         Add Winico support to the wm command on windows
Version:       $Revision: 1.8 $
Version:       $Revision: 1.7 $
Author:        Vince Darley <[email protected]>
State:         Final
Type:          Project
Tcl-Version:   8.4.0
Vote:          Done
Created:       06-Nov-2000
Post-History:
41
42
43
44
45
46
47
48

49
50
51
52
53
54
55
41
42
43
44
45
46
47

48
49
50
51
52
53
54
55







-
+







separately patched, and can also be made available).

~ Rationale

There have been many requests on news:comp.lang.tcl for this ability
in the Tk core, and several bug reports filed against Winico, and this
ability has been placed on the Tk 8.4 roadmap.
http://purl.org/tcl/home/software/tcltk/roadmap.tml
http://dev.scriptics.com/software/tcltk/roadmap.tml

The choice of ''wm iconbitmap'' is suggested, because ''wm
iconbitmap'' currently doesn't appear to do anything on Windows, yet
is the obvious choice for the user trying to set the window's icon
(e.g. many posts on news:comp.lang.tcl are actually asking why ''wm
iconbitmap'' doesn't do anything).

Changes to tip/9.tip.
1
2
3

4
5
6
7
8

9
10
11

12
13
14
15
16
17
18
19
1
2

3
4


5
6
7
8
9

10

11
12
13
14
15
16
17


-
+

-
-


+


-
+
-







TIP:            9
Title:          Tk Standard Library
Version:        $Revision: 1.3 $
Version:        $Revision: 1.1 $
Author:         Marty Backe <[email protected]>
Author:         hellins <[email protected]>
Author:         Larry W. Virden <[email protected]>
State:          Draft
Type:           Project
Tcl-Version:    8.4
Vote:           Pending
Created:        07-Nov-2000
Post-History:   
Post-History: 
Tcl-Version:    8.4

~ Abstract

A Tk standard library shall be bundled with the core Tcl/Tk
distribution.  The library will consist of general purpose widgets and
composite widgets for use in constructing Tcl/Tk applications.  The
library of Tk components will be written in Tcl/Tk.
64
65
66
67
68
69
70
71

72
73
74
75
76

77
78
79

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100

101

102
103
104
105
62
63
64
65
66
67
68

69


70
71

72
73
74

75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95

96
97
98
99
100
101
102







-
+
-
-


-
+


-
+




















-
+

+




 * The tklib shall be considered part of the "core" of Tcl/Tk. That
   is, releases of major/minor versions of Tcl/Tk shall not be made
   independent of tklib.

 * Additions to the tklib shall be made through a voting process,
   which is to be decided.

 * Tklib components shall include a test suite.  This test suite
 * Tklib components shall include a test suite.
   will be the means by which the library is verified as compatible
   with a new release of Tcl/Tk.

 * Tklib components shall include documentation to the same standards
   as Tcl/Tk, i.e., man pages, etc.  Let's continue the tradition of
   as Tcl/Tk, i.e., man pages, etc.  Lets continue the tradition of
   Tcl/Tk having the best documentation.

 * The tklib components will include one or more demonstration scripts that show 
 * The tklib components will include a demonstration script that shows
   to best effect all of the features and options provided by the
   component. A picture is worth a thousand words! The Tk, BWidgets,
   and Iwidgets demos are prime examples to be emulated.

 * Tklib components can be dependent on other tklib components.  If
   tklib and tcllib become coordinated efforts, the tklib components
   can be dependent on tcllib components.

 * The tklib can (and hopefully will) include megawidgets.

 * Tklib components shall be written in Tcl/Tk.

 * Tklib components shall be implemented in their own namespace and
   distributed in package form.

 * Tklib components do not have to be unique with regards to other
   tklib components, although there shall be differentiating
   characteristics between them. There is more then one way to skin a
   cat.

 * The tklib shall not contain applications, IDEs, or development
 * The tklib shall not contain applications, IDE's, or development
   tools.


~ Copyright

This document has been placed in the public domain.
Changes to tip/tipxml.dtd.
10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
10
11
12
13
14
15
16

17
18
19
20
21
22
23
24







-
+








<!-- Basic datatypes... -->
<!ENTITY % url 	      "CDATA"> <!-- only permit URLs, may be partial -->
<!ENTITY % num 	      "CDATA"> <!-- only permit non-negative integers -->

<!-- simplify header declaration (later) by partitioning -->
<!ENTITY % header.req "title, author+, status, history, created">
<!ENTITY % header.opt "discussions*, keyword*, obsoletes*, obsoleted*">
<!ENTITY % header.opt "discussions?, keyword*, obsoletes*, obsoleted*">

<!-- kinds of 'paragraphs': only inner can go inside lists -->
<!ENTITY % in.par     "para     | pre   | itemize | enumerate | describe" >
<!ENTITY % out.par    "%in.par; | quote | rule    | index     | image" >

<!-- Mixed content for conventional paragraphs -->
<!ENTITY % emphtext   "#PCDATA   | url | tipref">