Tcl Source Code

Check-in [8d3de5a4ff]
Login

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

Overview
Comment:Created branch core-8-1-0-synthetic
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | core-8-1-0-synthetic | core-8-1-0
Files: files | file ages | folders
SHA1: 8d3de5a4ff351209bc9d0feed3989ae2b9c4caab
User & Date: cvs2fossil 1999-04-22 20:31:08.000
Context
1999-04-22
20:31
Created branch core-8-1-0-synthetic Closed-Leaf check-in: 8d3de5a4ff user: cvs2fossil tags: core-8-1-0-synthetic, core-8-1-0
20:31
Entry for new WinSock code. check-in: 4a4924dadb user: redman tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to ChangeLog.
1
2
3
4

5







6

7



8
9
10
11
12
13
14
15
1999-04-22    <redma[email protected]>

	* win/tclWinPort.h:
	* win/tclWinSock.c: Added code to use WinSock 2.0 API on NT to

	avoid creating a window to handle sockets.  API not available on







	Win95 and needs to be fixed on Win98, until then continue to use

	the older (window-based) scheme on those two OSes.



	
1999-04-15    <[email protected]>

	* Merged 8.1 back into the main trunk

1999-04-13    <[email protected]>

	* library/encoding/gb2312.enc:
|

|
|
>
|
>
>
>
>
>
>
>
|
>
|
>
>
>
|







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
1999-04-29    <stanto[email protected]>

	* generic/tclParse.c: Fixed memory leak in CommandComplete.

1999-04-27    <[email protected]>

	* generic/tclPlatDecls.h: 
	* generic/tclIntPlatDecls.h: 
	* generic/tclIntDecls.h: 
	* generic/tclDecls.h: 
	* tools/genStubs.tcl: Added 'extern "C" {}' block around the stub
	table pointer declaration so the stub library can be used from
	C++. [Bug: 1934]

1999-04-23    <[email protected]>

	* generic/tclStubInit.c: 
	* tools/genStubs.tcl: Changed to avoid the need for forward
	declarations in stub initializers.

1999-04-15    <[email protected]>

	* Merged 8.1 back into the main trunk

1999-04-13    <[email protected]>

	* library/encoding/gb2312.enc:
Changes to README.
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
README:  Tcl

	Tcl is maintained, enhanced, and distributed freely as a
	service to the Tcl community by Scriptics Corporation.

RCS: @(#) $Id: README,v 1.17 1999/04/21 21:50:22 rjohnson Exp $

Contents
--------
    1. Introduction
    2. Documentation
    3. Compiling and installing Tcl
    4. Summary of changes in Tcl 8.1
    5. Development tools
    6. Tcl newsgroup
    7. Tcl contributed archive
    8. Tcl Resource Center
    9. Mailing lists
    10. Support and bug fixes
    11. Tcl version numbers

1. Introduction
---------------

Tcl provides a powerful platform for creating integration
applications that tie together diverse applications, protocols,
devices, and frameworks.  When paired with the Tk toolkit, Tcl
provides the fastest and most powerful way to create GUI applications
that run on PCs, Unix, and the Macintosh.  Tcl can also be used for a
variety of web-related tasks and for creating powerful command
languages for applications.

This directory contains the sources and documentation for Tcl.  The
information here corresponds to release 8.1.0.


Tcl 8.1 includes four major new features: Unicode support (all internal
strings are now stored in UTF-8 form), a new regular expression matcher
which surpass the features of Perl, support for multithreading, and a
new message catalog package.  For details on features,
incompatibilities, and potential problems with this release, see the
Tcl/Tk 8.1 Web page at http://www.scriptics.com/software/8.1.html or
refer to the "changes" file in this directory, which contains a
historical record of all changes to Tcl.

Tcl is a freely available open source package.  You can do virtually
anything you like with it, such as modifying it, redistributing it,
and selling it either in whole or in part.  See the file
"license.terms" for complete information.

2. Documentation
----------------

The best way to get started with Tcl is to read about Tcl on the
Scriptics Web site at:

	http://www.scriptics.com/scripting

Another good way to get started with Tcl is to read one of the
introductory books on Tcl:

    Practical Programming in Tcl and Tk, 2nd Edition, by Brent Welch,
    Prentice-Hall, 1997, ISBN 0-13-616830-2

    Tcl and the Tk Toolkit, by John Ousterhout,
    Addison-Wesley, 1994, ISBN 0-201-63337-X

    Exploring Expect, by Don Libes,
    O'Reilly and Associates, 1995, ISBN 1-56592-090-2

Other books are listed at
http://www.scriptics.com/resource/doc/books/

There is also an official home for Tcl and Tk on the Scriptics Web site:

	http://www.scriptics.com

These Web pages include information about the latest releases, products
related to Tcl and Tk, reports on bug fixes and porting issues, HTML
versions of the manual pages, and pointers to many other Tcl/Tk Web
pages at other sites.  Check them out!


2a. Unix Documentation
----------------------

The "doc" subdirectory in this release contains a complete set of
reference manual entries for Tcl.  Files with extension ".1" are for
programs (for example, tclsh.1); files with extension ".3" are for C

|
<
<

|






<
|
|
|
|
|
|
|



<








|
|
>

<
<
<
<
<
|
<
<







|

|
<
|
|

<
<
|
<
<
|
<
<

<
<
|
<
|

<
|
|

<
<
|
<
>







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
README:  Tcl
    This is the Tcl 8.1 source distribution.



RCS: @(#) $Id: README,v 1.17.2.1 1999/04/22 23:04:25 welch Exp $

Contents
--------
    1. Introduction
    2. Documentation
    3. Compiling and installing Tcl

    4. Development tools
    5. Tcl newsgroup
    6. Tcl contributed archive
    7. Tcl Resource Center
    8. Mailing lists
    9. Support and Training
    10. Thank You

1. Introduction
---------------

Tcl provides a powerful platform for creating integration
applications that tie together diverse applications, protocols,
devices, and frameworks.  When paired with the Tk toolkit, Tcl
provides the fastest and most powerful way to create GUI applications
that run on PCs, Unix, and the Macintosh.  Tcl can also be used for a
variety of web-related tasks and for creating powerful command
languages for applications.

Tcl is maintained, enhanced, and distributed freely as a
service to the Tcl community by Scriptics Corporation.
The official home for Tcl/Tk is on the Scriptics Web site:






    http://www.scriptics.com



Tcl is a freely available open source package.  You can do virtually
anything you like with it, such as modifying it, redistributing it,
and selling it either in whole or in part.  See the file
"license.terms" for complete information.

2. Documentation
---------------

Extensive documentation is available at our website.  The

home page for this release is
    http://www.scriptics.com/software/8.1.html



Information about new features in 8.1 can be found at


    http://www.scriptics.com/software/whatsnew81.html





Detailed release notes can be found at

    http://www.scriptics.com/software/relnotes/tcl8.1


Information about Tcl itself can be found at
    http://www.scriptics.com/scripting/



There are many Tcl books on the market.  Most are listed at

    http://www.scriptics.com/resource/doc/books/

2a. Unix Documentation
----------------------

The "doc" subdirectory in this release contains a complete set of
reference manual entries for Tcl.  Files with extension ".1" are for
programs (for example, tclsh.1); files with extension ".3" are for C
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

		man Tcl

2b. Windows Documentation
-------------------------

The "doc/help" subdirectory in this release contains a complete set of
Windows help files for TclPro.  Once you install this Tcl release, a
shortcut to the Windows help Tcl documentation will appear in the
"Start" menu:

	Start | Programs | Tcl | Tcl Help

3. Compiling and installing Tcl
-------------------------------

This release contains everything you should need to compile and run
Tcl under UNIX, PCs (either Windows NT, Windows 95, or Win 3.1 with
Win32s), and Macintoshes.

Before trying to compile Tcl you should do the following things:

    (a) Check for a binary release.  Pre-compiled binary releases are
        available now for PCs, Macintoshes, and several flavors of UNIX.
        Binary releases are much easier to install than source releases.
        To find out whether a binary release is available for your
        platform, check the Scriptics Tcl Resource Center
        (http://www.scriptics.com/resource).  Also, check in
        the FTP directory from which you retrieved the base
        distribution.

    (b) Make sure you have the most recent patch release.  Look in the
	FTP directory from which you retrieved this distribution to see
	if it has been updated with patches.  Patch releases fix bugs
	without changing any features, so you should normally use the
	latest patch release for the version of Tcl that you want. 

Once you've done this, change to the "unix" subdirectory if you're
compiling under UNIX, "win" if you're compiling under Windows, or
"mac" if you're compiling on a Macintosh.  Then follow the instructions
in the README file in that directory for compiling Tcl, installing it,
and running the test suite.

4. Summary of changes in Tcl 8.1
--------------------------------

Here are the most significant changes in Tcl 8.1.  In addition to these
changes, there are several smaller changes and bug fixes.  See the file
"changes" for a complete list of all changes.

    1. Internationalization. Tcl has undergone a major revision to
    support international character sets:

    All strings in Tcl are now represented in UTF-8 instead of ASCII,
    so that Tcl now supports the full Unicode character set.  The
    representation of ASCII characters is unchanged (in UTF-8 anything
    that looks like an ASCII character is an ASCII character), but
    characters with the high-order bit set, such as those in ISO-8859,
    are represented with multi-byte sequences, as are all Unicode
    characters with values greater than 127.  This change does not
    affect Tcl scripts but it does affect C code that parses strings.
    Tcl automatically translates between UTF-8 and the normal encoding
    for the platform during interactions with the system.

    In Tcl scripts the backslash sequence \u can be used to enter
    16-bit Unicode characters.  \o and \x generate only 8-bit
    characters as before.

    There is a new "encoding" command that allows scripts to determine
    what encodings are available as well as to convert strings between
    different encodings.  The fconfigure command now supports a
    -encoding option for specifying the encoding of an open file or
    socket.  Tcl will automatically translate between the specified
    encoding and UTF-8 during I/O.

    There are several new C APIs that support UTF-8 and various
    encodings.  See the manual entry Utf.3 for procedures that
    translate between Unicode and UTF-8 and manipulate UTF-8 strings.
    See Encoding.3 for procedures that create new encodings and
    translate between encodings.  See ToUpper.3 for procedures that
    perform case conversions on UTF-8 strings.

    2. Binary data.  Binary data is handled differently in Tcl 8.1
    than in Tcl 8.0.  Tcl 8.1 uses the UTF-8 facilities to represent
    binary data: the character value zero is represented with a
    multi-byte sequence, so that (once again) strings in Tcl 8.1 never
    contain null bytes.  This means that binary data is now accepted
    everywhere in Tcl and Tk (in Tcl 8.0 the support for binary data
    was incomplete).  If you have C code that needs to manipulate the
    bytes of binary data (as opposed to just passing the data through)
    you should use a new object type called "byte array".  See the
    manual entry ByteArrObj.3 for information about procedures such as
    Tcl_GetByteArrayFromObj.

    3. Regular expressions.  Tcl 8.1 contains a brand new
    implementation of regular expressions from Henry Spencer.  The
    regular expression syntax has been greatly expanded to include
    most of the features in Perl.  In addition, the regexp engine
    supports Unicode and binary data.  See the doc/regexp.n manual
    entry for more details.

    4. Threads.  If configured with the --enable-threads flag, Tcl can
    now be compiled for use in a multi-threaded application.
    Individual threads are allowed to use one or more interpreters as
    long as each interpreter (and any slave interpreters) is only
    accessed by one thread.  Each thread runs its own event loop, and
    you can post events to other threads. There are new C APIs for
    mutexes, condition variables, and thread local storage.  See the
    doc/Thread.3 manual entry for more details.  Tk 8.1 is not yet
    multi-thread safe.  There is not yet support for tcl level use of
    threading except for a test command. (Compile tcltest and try
    testthread.)

    5. Message catalog. There is a new message catalog package which makes
    it easy to localize the strings in a script.  See the doc/msgcat.n
    manual entry for more details.

    6. Stubbs library for building extensions.  There is now a new
    way to build extensions for Tcl.  Instead of linking with the
    tcl shared library you can now link to a stubs library that gets
    built in this release.  By linking with the stubs library it
    is possible to use dynamically loaded extensions in staticlly
    built applications.  It will also be possible for some extensions
    to work for both Tcl 8.0 & 8.1 with out having to recompile.

5. Development tools
--------------------

A high quality set of commercial development tools is now available to
accelerate your Tcl application development.  Scriptics' TclPro
product provides a debugger, static code checker, packaging utility,
and bytecode compiler.  Visit the Scriptics Web site at:

	http://www.scriptics.com/tclpro

for more information on TclPro and for a free 30-day evaluation
download.

6. Tcl newsgroup
----------------

There is a network news group "comp.lang.tcl" intended for the
exchange of information about Tcl, Tk, and related applications.  The
newsgroup is a greata place to ask general information questions.  For
bug reports, please see the "Support and bug fixes" section below.

7. Tcl contributed archive
--------------------------

Many people have created exciting packages and applications based on Tcl
and/or Tk and made them freely available to the Tcl community.  An archive
of these contributions is kept on the machine ftp.neosoft.com.  You
can access the archive using anonymous FTP;  the Tcl contributed archive is
in the directory "/pub/tcl".  The archive also contains several FAQ
("frequently asked questions") documents that provide solutions to problems
that are commonly encountered by TCL newcomers.

8. Tcl Resource Center
----------------------

Visit http://www.scriptics.com/resource/ to see an annotated index of
many Tcl resources available on the World Wide Web.  This includes
papers, books, and FAQs, as well as development tools, extensions,
applications, binary releases, and patches.  You can also recommend
additional URLs for the resource center using the forms labeled "Add a
Resource".

9. Mailing lists
----------------

A couple of  Mailing List have been set up to discuss Macintosh or
Windows related Tcl issues.  To subscribe send a message to:
	
	[email protected]
	[email protected]







|








<
<
<
|
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
|
<
<
<
<
<

<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|









|
<

|







|










|









|







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

		man Tcl

2b. Windows Documentation
-------------------------

The "doc/help" subdirectory in this release contains a complete set of
Windows help files for Tcl.  Once you install this Tcl release, a
shortcut to the Windows help Tcl documentation will appear in the
"Start" menu:

	Start | Programs | Tcl | Tcl Help

3. Compiling and installing Tcl
-------------------------------




There are brief notes in the unix/README, win/README, and mac/README

about compiling on these different platforms.  There is additional








information about building Tcl from sources at





    http://www.scriptics.com/support/howto/compile.html
























































































4. TclPro Development tools
--------------------

A high quality set of commercial development tools is now available to
accelerate your Tcl application development.  Scriptics' TclPro
product provides a debugger, static code checker, packaging utility,
and bytecode compiler.  Visit the Scriptics Web site at:

	http://www.scriptics.com/tclpro

for more information on TclPro and for a free evaluation download.


5. Tcl newsgroup
----------------

There is a network news group "comp.lang.tcl" intended for the
exchange of information about Tcl, Tk, and related applications.  The
newsgroup is a greata place to ask general information questions.  For
bug reports, please see the "Support and bug fixes" section below.

6. Tcl contributed archive
--------------------------

Many people have created exciting packages and applications based on Tcl
and/or Tk and made them freely available to the Tcl community.  An archive
of these contributions is kept on the machine ftp.neosoft.com.  You
can access the archive using anonymous FTP;  the Tcl contributed archive is
in the directory "/pub/tcl".  The archive also contains several FAQ
("frequently asked questions") documents that provide solutions to problems
that are commonly encountered by TCL newcomers.

7. Tcl Resource Center
----------------------

Visit http://www.scriptics.com/resource/ to see an annotated index of
many Tcl resources available on the World Wide Web.  This includes
papers, books, and FAQs, as well as development tools, extensions,
applications, binary releases, and patches.  You can also recommend
additional URLs for the resource center using the forms labeled "Add a
Resource".

8. Mailing lists
----------------

A couple of  Mailing List have been set up to discuss Macintosh or
Windows related Tcl issues.  To subscribe send a message to:
	
	[email protected]
	[email protected]
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
would just like to receive more information about the list without
subscribing put the line:

	information mactcl
	
in the body instead (or wintcl).

10. Support and bug fixes
-------------------------

Scriptics is very interested in receiving bug reports, patches, and
suggestions for improvements.  We prefer that you send this
information to us via the bug form on the Scriptics Web site, rather
than emailing us directly.  The bug form is at:

	http://www.scriptics.com/support/bugForm.html

The bug form was designed to give uniform structure to bug reports as
well as to solicit enough information to minimize followup questions.
The bug form also includes an option to automatically post your report
on comp.lang.tcl.  We strongly recommend that you select this option
because someone else who reads comp.lang.tcl may be able to offer a
solution.

When reporting bugs, please provide full information about the Tcl/Tk
version and the platform on which you are running Tcl/Tk.  Also,
please include a short tclsh script that we can use to reproduce the
bug.  Make sure that the script runs with a bare-bones tclsh and
doesn't depend on any extensions or other programs, particularly those
that exist only at your site.  Also, please include three additional
pieces of information with the script:

    (a) how do we use the script to make the problem happen (e.g.
	what things do we click on, in what order)?
    (b) what happens when you do these things (presumably this is
        undesirable)?
    (c) what did you expect to happen instead?

We will log and follow-up on each bug, although we cannot promise a
specific turn-around time.  Enhancements may take longer and may not
happen at all unless there is widespread support for them (we're
trying to slow the rate at which Tcl/Tk turns into a kitchen sink).
It's very difficult to make incompatible changes to Tcl/Tk at this
point, due to the size of the installed base.








|
|















<
<
<
<
<
<
<
<
<
<
<
<
<
<







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
would just like to receive more information about the list without
subscribing put the line:

	information mactcl
	
in the body instead (or wintcl).

9. Support and Training
------------------------

Scriptics is very interested in receiving bug reports, patches, and
suggestions for improvements.  We prefer that you send this
information to us via the bug form on the Scriptics Web site, rather
than emailing us directly.  The bug form is at:

	http://www.scriptics.com/support/bugForm.html

The bug form was designed to give uniform structure to bug reports as
well as to solicit enough information to minimize followup questions.
The bug form also includes an option to automatically post your report
on comp.lang.tcl.  We strongly recommend that you select this option
because someone else who reads comp.lang.tcl may be able to offer a
solution.















We will log and follow-up on each bug, although we cannot promise a
specific turn-around time.  Enhancements may take longer and may not
happen at all unless there is widespread support for them (we're
trying to slow the rate at which Tcl/Tk turns into a kitchen sink).
It's very difficult to make incompatible changes to Tcl/Tk at this
point, due to the size of the installed base.

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
	http://www.scriptics.com/training

Also see the following Web site for links to other organizations that
offer Tcl/Tk training:

	http://www.scriptics.com/resource/commercial/training

11. Tcl version numbers
-----------------------

You can test the current version of Tcl by examining the
tcl_version and tcl_patchLevel variables.  The tcl_patchLevel
variable follows the naming rules outlined below (e.g., 8.0.5).
The tcl_version just has the major.minor numbers in it (e.g., 8.0)

Each Tcl release is identified by two numbers separated by a dot, e.g.
6.7 or 7.0.  If a new release contains changes that are likely to break
existing C code or Tcl scripts then the major release number increments
and the minor number resets to zero: 6.0, 7.0, etc.  If a new release
contains only bug fixes and compatible changes, then the minor number
increments without changing the major number, e.g. 7.1, 7.2, etc.  If
you have C code or Tcl scripts that work with release X.Y, then they
should also work with any release X.Z as long as Z > Y.

Alpha and beta releases have an additional suffix of the form a2 or b1.
For example, Tcl 7.0b1 is the first beta release of Tcl version 7.0,
Tcl 7.0b2 is the second beta release, and so on.  A beta release is an
initial version of a new release, used to fix bugs and bad features before
declaring the release stable.  An alpha release is like a beta release,
except it's likely to need even more work before it's "ready for prime
time".  New releases are normally preceded by one or more alpha and beta
releases.  We hope that lots of people will try out the alpha and beta
releases and report problems.  We'll make new alpha/beta releases to fix
the problems, until eventually there is a beta release that appears to
be stable.  Once this occurs we'll make the final release.

We can't promise to maintain compatibility among alpha and beta releases.
For example, release 7.1b2 may not be backward compatible with 7.1b1, even
though the final 7.1 release will be backward compatible with 7.0.  This
allows us to change new features as we find problems during beta testing.
We'll try to minimize incompatibilities between beta releases, but if
a major problem turns up then we'll fix it even if it introduces an
incompatibility.  Once the official release is made then there won't
be any more incompatibilities until the next release with a new major
version number.

(Note: This compatibility is true for Tcl scripts, but historically
the Tcl C APIs have changed enough between releases that you may need
to work a bit to upgrade extensions.)

Patch releases now have a suffix such as ".4" or ".5".  Prior to
version 8.0.3, patch releases had the suffix "p1" or "p2".  So, the
8.0 release went to 8.0p1, 8.0p2, 8.0.3, 8.0.4, and 8.0.5.  The alphas
and betas continue to use the 'a' and 'b' letters in their
tcl_patchLevel.  Patch releases normally contain bug fixes only.  A
patch release (e.g Tcl 8.0.5) should be completely compatible with the
base release from which it is derived (e.g. Tcl 8.0), and you should
normally use the highest available patch release.

12. Thank You
-------------

We'd like to express our thanks to the Tcl community for all the
helpful suggestions, bug reports, and patches we have received.
Tcl/Tk has improved vastly and will continue to do so with your help.







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|





192
193
194
195
196
197
198




















































199
200
201
202
203
204
	http://www.scriptics.com/training

Also see the following Web site for links to other organizations that
offer Tcl/Tk training:

	http://www.scriptics.com/resource/commercial/training





















































10. Thank You
-------------

We'd like to express our thanks to the Tcl community for all the
helpful suggestions, bug reports, and patches we have received.
Tcl/Tk has improved vastly and will continue to do so with your help.
Changes to changes.
1
2
3
4
5
6
7
8
9
10
Recent user-visible changes to Tcl:

RCS: @(#) $Id: changes,v 1.43 1999/04/16 00:46:29 stanton Exp $

1. No more [command1] [command2] construct for grouping multiple
commands on a single command line.

2. Semi-colon now available for grouping commands on a line.

3. For a command to span multiple lines, must now use backslash-return


|







1
2
3
4
5
6
7
8
9
10
Recent user-visible changes to Tcl:

RCS: @(#) $Id: changes,v 1.43.4.1 1999/04/28 21:10:39 welch Exp $

1. No more [command1] [command2] construct for grouping multiple
commands on a single command line.

2. Semi-colon now available for grouping commands on a line.

3. For a command to span multiple lines, must now use backslash-return
4300
4301
4302
4303
4304
4305
4306

4307















4308
4309

4/6/99 (bug fix) Made the Env module I18N compliant. (surles)

4/6/99 (bug fix) Changed the FindVariable routine to TclpFindVariable,
that now does a case insensitive string comparison on Windows, and not
on UNIX. (surles)


















--------------- Released 8.1b3, April 6, 1999 ----------------------








>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|

4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325

4/6/99 (bug fix) Made the Env module I18N compliant. (surles)

4/6/99 (bug fix) Changed the FindVariable routine to TclpFindVariable,
that now does a case insensitive string comparison on Windows, and not
on UNIX. (surles)

--------------- Released 8.1b3, April 6, 1999 ----------------------

4/9/99 (bug fix)  Fixed notifier deadlock situation when the pipe used
to talk back notifier thread is filled with data.  Found as a result of the
focus.test for Tk hanging. (redman)

4/13/99 (bug fix) Fixed bug where socket -async combined with
fileevent for writing did not work under Windows NT. (redman)

4/13/99 (encoding fix) Restored the double byte definition of GB2312
and added the EUC-CN encoding.  EUC-CN is a variant of GB2312 that
shifts the characters into bytes with the high bit set and includes
ASCII as a subset. (stanton)

4/27/99 (bug fix) Added 'extern "C" {}' block around the stub table
pointer declaration so the stub library can be used from C++. (stanton)

--------------- Released 8.1 final, April 29, 1999 ----------------------

Changes to doc/Access.3.
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
'\"
'\" Copyright (c) 1998-1999 Scriptics Corportation
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" RCS: @(#) $Id: Access.3,v 1.1 1999/04/17 01:36:32 hershey Exp $
'\" 
.so man.macros
.TH Tcl_Access 3 8.1 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_Access, Tcl_Stat \- check file permissions and other attributes
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
int
\fBTcl_Access\fR(\fpath\fR, \fImode\fR)
.sp
int
\fBTcl_Stat\fR(\fIpath\fR, \fIbufPtr\fR)
.SH ARGUMENTS
.AS struct stat *bufPtr
.AP CONST char *path in
Native name of the file to check the attributes of.
.AP int mode in
Mask consisting of one or more of R_OK, W_OK, X_OK and F_OK.  R_OK,
W_OK and X_OK request checking whether the file exists and  has  read,
write and  execute  permissions, respectively.  F_OK just requests
checking for the existence of the file.
.AP struct stat *bufPtr out
The structure that contains the result.
.BE

.SH DESCRIPTION
.PP
There are two reasons for calling \fBTcl_Access\fR and \fBTcl_Stat\fR
rather than calling system level functions \fBaccess\fR and \fBstat\fR
directly.  First, the Windows implementation of both functions fixes
some bugs in the system level calls.  Second, both \fBTcl_Access\fR
and \fBTcl_Stat\fR (as well as \fBTcl_OpenFileChannelProc\fR) hook
into a linked list of functions, the first of which checks for the
existence of \fBpath\fR in a Zip file rather than on disc.  The
hooking behavior is necessary for applications wrapped with TclPro
Wrapper.
.PP
\fBTcl_Access\fR checks whether the process would be allowed to read,
write or test for existence of the file (or other file system object)
whose name is pathname.   If pathname is a symbolic link on Unix,
then permissions of the file referred by this symbolic link are
tested.
.PP
On success (all requested permissions granted), zero is returned.  On
error (at least one bit in mode asked for a permission that is denied,
or some other  error occurred), -1 is returned.
.PP
\fBTcl_Stat\fR returns the stat structure with information about the
specified file.  You do not need any access rights to the file to get
this information but you need search rights to all directories named
in the path leading to the file.  










.SH KEYWORDS
statc access






|











|


|

|
|






|










|
|
<
<











|
|
|
|
>
>
>
>
>
>
>
>
>


|
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
'\"
'\" Copyright (c) 1998-1999 Scriptics Corportation
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" RCS: @(#) $Id: Access.3,v 1.1.2.1 1999/04/27 03:03:22 hershey Exp $
'\" 
.so man.macros
.TH Tcl_Access 3 8.1 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_Access, Tcl_Stat \- check file permissions and other attributes
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
int
\fBTcl_Access\fR(\fIpath\fR, \fImode\fR)
.sp
int
\fBTcl_Stat\fR(\fIpath\fR, \fIstatPtr\fR)
.SH ARGUMENTS
.AS stat *statPtr in
.AP char *path in
Native name of the file to check the attributes of.
.AP int mode in
Mask consisting of one or more of R_OK, W_OK, X_OK and F_OK.  R_OK,
W_OK and X_OK request checking whether the file exists and  has  read,
write and  execute  permissions, respectively.  F_OK just requests
checking for the existence of the file.
.AP stat *statPtr out
The structure that contains the result.
.BE

.SH DESCRIPTION
.PP
There are two reasons for calling \fBTcl_Access\fR and \fBTcl_Stat\fR
rather than calling system level functions \fBaccess\fR and \fBstat\fR
directly.  First, the Windows implementation of both functions fixes
some bugs in the system level calls.  Second, both \fBTcl_Access\fR
and \fBTcl_Stat\fR (as well as \fBTcl_OpenFileChannelProc\fR) hook
into a linked list of functions.  This allows the possibity to reroute
file access to alternative media or access methods.


.PP
\fBTcl_Access\fR checks whether the process would be allowed to read,
write or test for existence of the file (or other file system object)
whose name is pathname.   If pathname is a symbolic link on Unix,
then permissions of the file referred by this symbolic link are
tested.
.PP
On success (all requested permissions granted), zero is returned.  On
error (at least one bit in mode asked for a permission that is denied,
or some other  error occurred), -1 is returned.
.PP
\fBTcl_Stat\fR fills the stat structure \fIstatPtr\fR with information
about the specified file.  You do not need any access rights to the
file to get this information but you need search rights to all
directories named in the path leading to the file.  The stat structure
includes info regarding device, inode (always 0 on Windows),
priviledge mode, nlink (always 1 on Windows), user id (always 0 on
Windows), group id (always 0 on Windows), rdev (same as device on
Windows), size, last access time, last modification time, and creation
time.
.PP
If \fIpath\fR exists, \fBTcl_Stat\fR returns 0 and the stat structure
is filled with data.  Otherwise, -1 is returned, and no stat info is
given.

.SH KEYWORDS
stat access
Changes to doc/Encoding.3.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
'\"
'\" Copyright (c) 1997-1998 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" RCS: @(#) $Id: Encoding.3,v 1.2 1999/04/16 00:46:31 stanton Exp $
'\" 
.so man.macros
.TH Tcl_GetEncoding 3 "8.1" Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_GetEncoding, Tcl_FreeEncoding, Tcl_ExternalToUtfDString, Tcl_ExternalToUtf, Tcl_UtfToExternalDString, Tcl_UtfToExternal, Tcl_GetEncodingName, Tcl_SetSystemEncoding, Tcl_GetEncodingNames, Tcl_CreateEncoding, Tcl_GetDefaultEncodingDir, Tcl_SetDefaultEncodingDir \- procedures for creating and using encodings.





.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
Tcl_Encoding
\fBTcl_GetEncoding\fR(\fIinterp, name\fR)
.sp






|





|
|
|
|
|
>







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
'\"
'\" Copyright (c) 1997-1998 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" RCS: @(#) $Id: Encoding.3,v 1.2.4.2 1999/04/28 17:08:28 kenj Exp $
'\" 
.so man.macros
.TH Tcl_GetEncoding 3 "8.1" Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_GetEncoding, Tcl_FreeEncoding, Tcl_ExternalToUtfDString,
Tcl_ExternalToUtf, Tcl_UtfToExternalDString, Tcl_UtfToExternal,
Tcl_WinTCharToUtf, Tcl_WinUtfToTChar,
Tcl_GetEncodingName, Tcl_SetSystemEncoding, Tcl_GetEncodingNames,
Tcl_CreateEncoding, Tcl_GetDefaultEncodingDir,
Tcl_SetDefaultEncodingDir \- procedures for creating and using encodings.
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
Tcl_Encoding
\fBTcl_GetEncoding\fR(\fIinterp, name\fR)
.sp
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
void 
\fBTcl_UtfToExternalDString\fR(\fIencoding, src, srcLen, dstPtr\fR)
.sp
int
\fBTcl_UtfToExternal\fR(\fIinterp, encoding, src, srcLen, flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr, 
	dstCharsPtr\fR)
.sp






char *
\fBTcl_GetEncodingName\fR(\fIencoding\fR)
.sp
int
\fBTcl_SetSystemEncoding\fR(\fIinterp, name\fR)
.sp
void
\fBTcl_GetEncodingNames\fR(\fIinterp\fR)
.sp
Tcl_Encoding
\fBTcl_CreateEncoding\fR(\fItypePtr\fR)

.sp
char *
\fBTcl_GetDefaultEncodingDir\fR(\fIvoid\fR)
.sp
void
\fBTcl_SetDefaultEncodingDir\fR(\fIpath\fR)








>
>
>
>
>
>











<







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
void 
\fBTcl_UtfToExternalDString\fR(\fIencoding, src, srcLen, dstPtr\fR)
.sp
int
\fBTcl_UtfToExternal\fR(\fIinterp, encoding, src, srcLen, flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr, 
	dstCharsPtr\fR)
.sp
char *
\fBTcl_WinTCharToUtf\fR(\fItsrc, srcLen, dstPtr\fR)
.sp
TCHAR *
\fBTcl_WinUtfToTChar\fR(\fIsrc, srcLen, dstPtr\fR)
.sp
char *
\fBTcl_GetEncodingName\fR(\fIencoding\fR)
.sp
int
\fBTcl_SetSystemEncoding\fR(\fIinterp, name\fR)
.sp
void
\fBTcl_GetEncodingNames\fR(\fIinterp\fR)
.sp
Tcl_Encoding
\fBTcl_CreateEncoding\fR(\fItypePtr\fR)

.sp
char *
\fBTcl_GetDefaultEncodingDir\fR(\fIvoid\fR)
.sp
void
\fBTcl_SetDefaultEncodingDir\fR(\fIpath\fR)

68
69
70
71
72
73
74
75
76


77
78
79
80
81
82
83
84
85
Name of encoding to load.
.AP Tcl_Encoding encoding in
The encoding to query, free, or use for converting text.  If \fIencoding\fR is 
NULL, the current system encoding is used.
.AP "CONST char" *src in
For the \fBTcl_ExternalToUtf\fR functions, an array of bytes in the
specified encoding that are to be converted to UTF-8.  For the
\fBTcl_UtfToExternal\fR functions, an array of UTF-8 characters to be
converted to the specified encoding.  


.AP int srcLen in 
Length of \fIsrc\fR in bytes.  If the length is negative, the 
encoding-specific length of the string is used.
.AP Tcl_DString *dstPtr out
Pointer to an uninitialized or free \fBTcl_DString\fR in which the converted
result will be stored.
.AP int flags in
Various flag bits OR-ed together.  
TCL_ENCODING_START signifies that the







|
|
>
>

|







74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
Name of encoding to load.
.AP Tcl_Encoding encoding in
The encoding to query, free, or use for converting text.  If \fIencoding\fR is 
NULL, the current system encoding is used.
.AP "CONST char" *src in
For the \fBTcl_ExternalToUtf\fR functions, an array of bytes in the
specified encoding that are to be converted to UTF-8.  For the
\fBTcl_UtfToExternal\fR and \fBTcl_WinUtfToTChar\fR functions, an array of
UTF-8 characters to be converted to the specified encoding.  
.AP "CONST TCHAR" *tsrc in
An array of Windows TCHAR characters to convert to UTF-8.
.AP int srcLen in 
Length of \fIsrc\fR or \fItsrc\fR in bytes.  If the length is negative, the 
encoding-specific length of the string is used.
.AP Tcl_DString *dstPtr out
Pointer to an uninitialized or free \fBTcl_DString\fR in which the converted
result will be stored.
.AP int flags in
Various flag bits OR-ed together.  
TCL_ENCODING_START signifies that the
219
220
221
222
223
224
225


































226
227
228
229
230
231
232
233
the source buffer and up to \fIdstLen\fR converted bytes are stored in
\fIdst\fR.  In all cases, \fI*srcReadPtr\fR is filled with the number of
bytes that were successfully converted from \fIsrc\fR and \fI*dstWrotePtr\fR
is filled with the corresponding number of bytes that were stored in
\fIdst\fR.  The return values are the same as the return values for
\fBTcl_ExternalToUtf\fR.
.PP


































\fBTcl_GetEncodingName\fR is roughly the inverse of \fBTk_GetEncoding\fR.
Given an \fIencoding\fR, the return value is the \fIname\fR argument that
was used to create the encoding.  The string returned by 
\fBTcl_GetEncodingName\fR is only guaranteed to persist until the
\fIencoding\fR is deleted.  The caller must not modify this string.
.PP
\fBTcl_SetSystemEncoding\fR sets the default encoding that should be used
whenever the user passes a NULL value for the \fIencoding\fR argument to







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|







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
the source buffer and up to \fIdstLen\fR converted bytes are stored in
\fIdst\fR.  In all cases, \fI*srcReadPtr\fR is filled with the number of
bytes that were successfully converted from \fIsrc\fR and \fI*dstWrotePtr\fR
is filled with the corresponding number of bytes that were stored in
\fIdst\fR.  The return values are the same as the return values for
\fBTcl_ExternalToUtf\fR.
.PP
\fBTcl_WinUtfToTChar\fR and \fBTcl_WinTCharToUtf\fR are
Windows-only convenience
functions for converting between UTF-8 and Windows strings.  On Windows 95
(as with the Macintosh and Unix operating systems),
all strings exchanged between Tcl and the operating system are "char"
based.  On Windows NT, some strings exchanged between Tcl and the
operating system are "char" oriented while others are in Unicode.  By
convention, in Windows a TCHAR is a character in the ANSI code page
on Windows 95 and a Unicode character on Windows NT.
.PP
If you planned to use the same "char" based interfaces on both Windows
95 and Windows NT, you could use \fBTcl_UtfToExternal\fR and
\fBTcl_ExternalToUtf\fR (or their \fBTcl_DString\fR equivalents) with an
encoding of NULL (the current system encoding).  On the other hand,
if you planned to use the Unicode interface when running on Windows NT
and the "char" interfaces when running on Windows 95, you would have
to perform the following type of test over and over in your program
(as represented in psuedo-code):
.CS
if (running NT) {
    encoding <- Tcl_GetEncoding("unicode");
    nativeBuffer <- Tcl_UtfToExternal(encoding, utfBuffer);
    Tcl_FreeEncoding(encoding);
} else {
    nativeBuffer <- Tcl_UtfToExternal(NULL, utfBuffer);
.CE
\fBTcl_WinUtfToTChar\fR and \fBTcl_WinTCharToUtf\fR automatically
handle this test and use the proper encoding based on the current
operating system.  \fBTcl_WinUtfToTChar\fR returns a pointer to
a TCHAR string, and \fBTcl_WinTCharToUtf\fR expects a TCHAR string
pointer as the \fIsrc\fR string.  Otherwise, these functions
behave identically to \fBTcl_UtfToExternalDString\fR and
\fBTcl_ExternalToUtfDString\fR.
.PP
\fBTcl_GetEncodingName\fR is roughly the inverse of \fBTcl_GetEncoding\fR.
Given an \fIencoding\fR, the return value is the \fIname\fR argument that
was used to create the encoding.  The string returned by 
\fBTcl_GetEncodingName\fR is only guaranteed to persist until the
\fIencoding\fR is deleted.  The caller must not modify this string.
.PP
\fBTcl_SetSystemEncoding\fR sets the default encoding that should be used
whenever the user passes a NULL value for the \fIencoding\fR argument to
Added doc/InitStubs.3.






















































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
'\"
'\" Copyright (c) 1999 Scriptics Corportation
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" RCS: @(#) $Id: InitStubs.3,v 1.1.2.2 1999/04/29 02:06:53 stanton Exp $
'\" 
.so man.macros
.TH Tcl_InitStubs 3 8.1 Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_InitStubs \- initialize the Tcl stubs mechanism
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
char *
\fBTcl_InitStubs\fR(\fIinterp, version, exact\fR)
.SH ARGUMENTS
.AS Tcl_Interp *interp in
.AP Tcl_Interp *interp in
Tcl interpreter handle.
.AP char *version in
A version string consisting of one or more decimal numbers
separated by dots.
.AP int exact in
Non-zero means that only the particular version specified by
\fIversion\fR is acceptable.
Zero means that versions newer than \fIversion\fR are also
acceptable as long as they have the same major version number
as \fIversion\fR.
.BE
.SH INTRODUCTION
.PP
The Tcl stubs mechanism defines a way to dynamically bind
extensions to a particular Tcl implementation at run time.
This provides two significant benefits to Tcl users:
.IP 1) 5
Extensions that use the stubs mechanism can be loaded into
multiple versions of Tcl without being recompiled or
relinked.
.IP 2) 5
Extensions that use the stubs mechanism can be dynamically
loaded into statically-linked Tcl applications.
.PP
The stubs mechanism accomplishes this by exporting function tables
that define an interface to the Tcl API.  The extension then accesses
the Tcl API through offsets into the function table, so there are no
direct references to any of the Tcl library's symbols.  This
redirection is transparent to the extension, so an extension writer
can continue to use all public Tcl functions as documented.
.PP
The stubs mechanism requires no changes to applications incorporating
Tcl interpreters.  Only developers creating C-based Tcl extensions
need to take steps to use the stubs mechanism with their extensions.
.PP
Enabling the stubs mechanism for an extension requires the following
steps:
.IP 1) 5
Call \fBTcl_InitStubs\fR in the extension before calling any other
Tcl functions.
.IP 2) 5
Define the USE_TCL_STUBS symbol.  Typically, you would include the
-DUSE_TCL_STUBS flag when compiling the extension.
.IP 3) 5
Link the extension with the Tcl stubs library instead of the standard
Tcl library.  On Unix platforms, the library name is
\fIlibtclstub8.1.a\fR; on Windows platforms, the library name is
\fItclstub81.lib\fR.
.PP
If the extension also requires the Tk API, it must also call
\fBTk_InitStubs\fR to initialize the Tk stubs interface and link
with the Tk stubs libraries.  See the \fBTk_InitStubs\fR page for
more information.
.SH DESCRIPTION
\fBTcl_InitStubs\fR attempts to initialize the stub table pointers
and ensure that the correct version of Tcl is loaded.  In addition
to an interpreter handle, it accepts as arguments a version number
and a Boolean flag indicating whether the extension requires
an exact version match or not.  If \fIexact\fR is 0, then the
extension is indicating that newer versions of Tcl are acceptable
as long as they have the same major version number as \fIversion\fR;
non-zero means that only the specified \fIversion\fR is acceptable.
\fBTcl_InitStubs\fR returns a string containing the actual version
of Tcl satisfying the request, or NULL if the Tcl version is not
acceptable, does not support stubs, or any other error condition occurred.
.SH "SEE ALSO"
\fBTk_InitStubs\fR
.SH KEYWORDS
stubs
Changes to doc/Notifier.3.
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
'\"

'\" Copyright (c) 1995-1997 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" RCS: @(#) $Id: Notifier.3,v 1.4 1999/04/21 21:50:22 rjohnson Exp $
'\" 
.so man.macros
.TH Notifier 3 8.0 Tcl "Tcl Library Procedures"
.BS
.VS
.SH NAME
Tcl_CreateEventSource, Tcl_DeleteEventSource, Tcl_SetMaxBlockTime, Tcl_QueueEvent, Tcl_DeleteEvents, Tcl_WaitForEvent, Tcl_SetTimer, Tcl_ServiceAll, Tcl_ServiceEvent, Tcl_GetServiceMode, Tcl_SetServiceMode \- the event queue and notifier interfaces

.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp

\fBTcl_CreateEventSource\fR(\fIsetupProc, checkProc, clientData\fB)\fR
.sp

\fBTcl_DeleteEventSource\fR(\fIsetupProc, checkProc, clientData\fB)\fR
.sp

\fBTcl_SetMaxBlockTime\fR(\fItimePtr\fB)\fR
.sp

\fBTcl_QueueEvent\fR(\fIevPtr, position\fR)

.sp

\fBTcl_ThreadQueueEvent\fR(\fIthreadId, evPtr, position\fR)
.VS


.sp

\fBTcl_DeleteEvents\fR(\fIdeleteProc, clientData\fR)
.sp
int
\fBTcl_WaitForEvent\fR(\fItimePtr\fR)
.sp
ClientData
\fBTcl_InitNotifier\fR()
.sp

\fBTcl_FinalizeNotifier\fR(\fIclientData\fR)
.sp

\fBTcl_AlertNotifier\fR(\fIclientData\fR)
.sp

\fBTcl_ThreadAlert\fR(\fIthreadId\fR)
.sp

\fBTcl_SetTimer\fR(\fItimePtr\fR)
.sp
int
\fBTcl_ServiceAll\fR()
.sp
int
\fBTcl_ServiceEvent\fR(\fIflags\fR)
.sp
int
\fBTcl_GetServiceMode\fR()
.sp
int		
\fBTcl_SetServiceMode\fR(\fImode\fR)
.VE

.SH ARGUMENTS
.AS Tcl_EventDeleteProc milliseconds
.AS Tcl_EventSetupProc *setupProc
.AP Tcl_EventSetupProc *setupProc in
Procedure to invoke to prepare for event wait in \fBTcl_DoOneEvent\fR.
.AP Tcl_EventCheckProc *checkProc in
Procedure for \fBTcl_DoOneEvent\fR to invoke after waiting for
events.  Checks to see if any events have occurred and, if so,
queues them.
.AP ClientData clientData in

>





|


|

<

|
<




>
|

>
|

>
|

>

>

>

|
>
>

>
|

|
|




>


>
|

>
|

>

















<







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
'\"
'\" Copyright (c) 1998-1999 Scriptics Corporation
'\" Copyright (c) 1995-1997 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" RCS: @(#) $Id: Notifier.3,v 1.4.2.2 1999/04/29 02:06:54 stanton Exp $
'\" 
.so man.macros
.TH Notifier 3 8.1 Tcl "Tcl Library Procedures"
.BS

.SH NAME
Tcl_CreateEventSource, Tcl_DeleteEventSource, Tcl_SetMaxBlockTime, Tcl_QueueEvent, Tcl_ThreadQueueEvent, Tcl_ThreadAlert, Tcl_GetCurrentThread, Tcl_DeleteEvents, Tcl_InitNotifier, Tcl_FinalizeNotifier, Tcl_WaitForEvent, Tcl_AlertNotifier, Tcl_SetTimer, Tcl_ServiceAll, Tcl_ServiceEvent, Tcl_GetServiceMode, Tcl_SetServiceMode \- the event queue and notifier interfaces

.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
void
\fBTcl_CreateEventSource\fR(\fIsetupProc, checkProc, clientData\fR)
.sp
void
\fBTcl_DeleteEventSource\fR(\fIsetupProc, checkProc, clientData\fR)
.sp
void
\fBTcl_SetMaxBlockTime\fR(\fItimePtr\fR)
.sp
void
\fBTcl_QueueEvent\fR(\fIevPtr, position\fR)
.VS 8.1
.sp
void
\fBTcl_ThreadQueueEvent\fR(\fIthreadId, evPtr, position\fR)
.sp
void
\fBTcl_ThreadAlert\fR(\fIthreadId, clientData\fR)
.sp
Tcl_ThreadId
\fBTcl_GetCurrentThread\fR()
.sp
void
\fBTcl_DeleteEvents\fR(\fIdeleteProc, clientData\fR)
.sp
ClientData
\fBTcl_InitNotifier\fR()
.sp
void
\fBTcl_FinalizeNotifier\fR(\fIclientData\fR)
.sp
int
\fBTcl_WaitForEvent\fR(\fItimePtr\fR)
.sp
void
\fBTcl_AlertNotifier\fR(\fIclientData\fR)
.sp
void
\fBTcl_SetTimer\fR(\fItimePtr\fR)
.sp
int
\fBTcl_ServiceAll\fR()
.sp
int
\fBTcl_ServiceEvent\fR(\fIflags\fR)
.sp
int
\fBTcl_GetServiceMode\fR()
.sp
int		
\fBTcl_SetServiceMode\fR(\fImode\fR)
.VE

.SH ARGUMENTS
.AS Tcl_EventDeleteProc milliseconds

.AP Tcl_EventSetupProc *setupProc in
Procedure to invoke to prepare for event wait in \fBTcl_DoOneEvent\fR.
.AP Tcl_EventCheckProc *checkProc in
Procedure for \fBTcl_DoOneEvent\fR to invoke after waiting for
events.  Checks to see if any events have occurred and, if so,
queues them.
.AP ClientData clientData in
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
necessary.
.AP Tcl_Event *evPtr in
An event to add to the event queue.  The storage for the event must
have been allocated by the caller using \fBTcl_Alloc\fR or \fBckalloc\fR.
.AP Tcl_QueuePosition position in
Where to add the new event in the queue:  \fBTCL_QUEUE_TAIL\fR,
\fBTCL_QUEUE_HEAD\fR, or \fBTCL_QUEUE_MARK\fR.




.AP int flags in
What types of events to service.  These flags are the same as those
passed to \fBTcl_DoOneEvent\fR.
.AP Tcl_EventDeleteProc *deleteProc in
Procedure to invoke for each queued event in \fBTcl_DeleteEvents\fR.
.VS
.AP int mode in
Inidicates whether events should be serviced by \fBTcl_ServiceAll\fR.
Must be one of \fBTCL_SERVICE_NONE\fR or \fBTCL_SERVICE_ALL\fR.
.VE
.BE

.SH INTRODUCTION
.PP
.VS
The interfaces described here are used to customize the Tcl event
loop.  The two most common customizations are to add new sources of
events and to merge Tcl's event loop with some other event loop, such
as one provided by an application in which Tcl is embedded.  Each of
these tasks is described in a separate section below.
.VE
.PP
The procedures in this manual entry are the building blocks out of which
the Tcl event notifier is constructed.  The event notifier is the lowest
layer in the Tcl event mechanism.  It consists of three things:
.IP [1]
Event sources: these represent the ways in which events can be
generated.  For example, there is a timer event source that implements
the \fBTcl_CreateTimerHandler\fR procedure and the \fBafter\fR
command, and there is a file event source that implements the
\fBTcl_CreateFileHandler\fR procedure on Unix systems.  An event
source must work with the notifier to detect events at the right
times, record them on the event queue, and eventually notify
higher-level software that they have occurred.  The procedures
\fBTcl_CreateEventSource\fR, \fBTcl_DeleteEventSource\fR,
and \fBTcl_SetMaxBlockTime\fR, \fBTcl_QueueEvent\fR, and
\fBTcl_DeleteEvents\fR are used primarily by event sources.
.IP [2]

The event queue: there is a single queue for the whole application,
containing events that have been detected but not yet serviced.  Event
sources place events onto the queue so that they may be processed in
order at appropriate times during the event loop. The event queue
guarantees a fair discipline of event handling, so that no event
source can starve the others.  It also allows events to be saved for
servicing at a future time.
.VS



\fBTcl_QueueEvent\fR is used (primarily
by event sources) to add events to the event queue and 
\fBTcl_DeleteEvents\fR is used to remove events from the queue without
processing them.  See the manual entry for \fBThread\fR for a 
description of the \fBTcl_ThreadQueueEvent\fR procedure.

.IP [3]
The event loop: in order to detect and process events, the application
enters a loop that waits for events to occur, places them on the event
queue, and then processes them.  Most applications will do this by
calling the procedure \fBTcl_DoOneEvent\fR, which is described in a
separate manual entry.
.PP
Most Tcl applications need not worry about any of the internals of
the Tcl notifier.  However, the notifier now has enough flexibility
to be retargeted either for a new platform or to use an external event
loop (such as the Motif event loop, when Tcl is embedded in a Motif
application).  The procedures \fBTcl_WaitForEvent\fR and
\fBTcl_SetTimer\fR are normally implemented by Tcl, but may be
replaced with new versions to retarget the notifier (the \fBTcl_Sleep\fR,


\fBTcl_CreateFileHandler\fR, and \fBTcl_DeleteFileHandler\fR must
also be replaced; see CREATING A NEW NOTIFIER below for details).
The procedures \fBTcl_ServiceAll\fR, \fBTcl_ServiceEvent\fR,
\fBTcl_GetServiceMode\fR, and \fBTcl_SetServiceMode\fR are provided
to help connect Tcl's event loop to an external event loop such as
Motif's.
.SH "NOTIFIER BASICS"
.VE
.PP
The easiest way to understand how the notifier works is to consider
what happens when \fBTcl_DoOneEvent\fR is called.
\fBTcl_DoOneEvent\fR is passed a \fIflags\fR argument that indicates
what sort of events it is OK to process and also whether or not to
block if no events are ready.  \fBTcl_DoOneEvent\fR does the following
things:
.IP [1]
Check the event queue to see if it contains any events that can
be serviced.  If so, service the first possible event, remove it
.VS
from the queue, and return.  It does this by calling
\fBTcl_ServiceEvent\fR and passing in the \fIflags\fR argument.
.VE
.IP [2]
Prepare to block for an event.  To do this, \fBTcl_DoOneEvent\fR
invokes a \fIsetup procedure\fR in each event source.
The event source will perform event-source specific initialization and
.VS
possibly call \fBTcl_SetMaxBlockTime\fR to limit how long
.VE
\fBTcl_WaitForEvent\fR will block if no new events occur.
.IP [3]
Call \fBTcl_WaitForEvent\fR.  This procedure is implemented differently
on different platforms;  it waits for an event to occur, based on the
information provided by the event sources.







>
>
>
>



<
<
|








<





<

















>
|






|
>
>
>



|
|
|













|
>
>


















|







|







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
necessary.
.AP Tcl_Event *evPtr in
An event to add to the event queue.  The storage for the event must
have been allocated by the caller using \fBTcl_Alloc\fR or \fBckalloc\fR.
.AP Tcl_QueuePosition position in
Where to add the new event in the queue:  \fBTCL_QUEUE_TAIL\fR,
\fBTCL_QUEUE_HEAD\fR, or \fBTCL_QUEUE_MARK\fR.
.AP Tcl_ThreadId threadId in
A unique identifier for a thread.
.AP Tcl_EventDeleteProc *deleteProc in
Procedure to invoke for each queued event in \fBTcl_DeleteEvents\fR.
.AP int flags in
What types of events to service.  These flags are the same as those
passed to \fBTcl_DoOneEvent\fR.


.VS 8.1
.AP int mode in
Inidicates whether events should be serviced by \fBTcl_ServiceAll\fR.
Must be one of \fBTCL_SERVICE_NONE\fR or \fBTCL_SERVICE_ALL\fR.
.VE
.BE

.SH INTRODUCTION
.PP

The interfaces described here are used to customize the Tcl event
loop.  The two most common customizations are to add new sources of
events and to merge Tcl's event loop with some other event loop, such
as one provided by an application in which Tcl is embedded.  Each of
these tasks is described in a separate section below.

.PP
The procedures in this manual entry are the building blocks out of which
the Tcl event notifier is constructed.  The event notifier is the lowest
layer in the Tcl event mechanism.  It consists of three things:
.IP [1]
Event sources: these represent the ways in which events can be
generated.  For example, there is a timer event source that implements
the \fBTcl_CreateTimerHandler\fR procedure and the \fBafter\fR
command, and there is a file event source that implements the
\fBTcl_CreateFileHandler\fR procedure on Unix systems.  An event
source must work with the notifier to detect events at the right
times, record them on the event queue, and eventually notify
higher-level software that they have occurred.  The procedures
\fBTcl_CreateEventSource\fR, \fBTcl_DeleteEventSource\fR,
and \fBTcl_SetMaxBlockTime\fR, \fBTcl_QueueEvent\fR, and
\fBTcl_DeleteEvents\fR are used primarily by event sources.
.IP [2]
The event queue: for non-threaded applications,
there is a single queue for the whole application,
containing events that have been detected but not yet serviced.  Event
sources place events onto the queue so that they may be processed in
order at appropriate times during the event loop. The event queue
guarantees a fair discipline of event handling, so that no event
source can starve the others.  It also allows events to be saved for
servicing at a future time.
.VS 8.1
Threaded applications work in a
similar manner, except that there is a separate event queue for
each thread containing a Tcl interpreter.
\fBTcl_QueueEvent\fR is used (primarily
by event sources) to add events to the event queue and 
\fBTcl_DeleteEvents\fR is used to remove events from the queue without
processing them.  In a threaded application, \fBTcl_QueueEvent\fR adds
an event to the current thread's queue, and \fBTcl_ThreadQueueEvent\fR
adds an event to a queue in a specific thread.
.IP [3]
The event loop: in order to detect and process events, the application
enters a loop that waits for events to occur, places them on the event
queue, and then processes them.  Most applications will do this by
calling the procedure \fBTcl_DoOneEvent\fR, which is described in a
separate manual entry.
.PP
Most Tcl applications need not worry about any of the internals of
the Tcl notifier.  However, the notifier now has enough flexibility
to be retargeted either for a new platform or to use an external event
loop (such as the Motif event loop, when Tcl is embedded in a Motif
application).  The procedures \fBTcl_WaitForEvent\fR and
\fBTcl_SetTimer\fR are normally implemented by Tcl, but may be
replaced with new versions to retarget the notifier (the
\fBTcl_InitNotifier\fR, \fBTcl_AlertNotifier\fR,
\fBTcl_FinalizeNotifier\fR, \fBTcl_Sleep\fR,
\fBTcl_CreateFileHandler\fR, and \fBTcl_DeleteFileHandler\fR must
also be replaced; see CREATING A NEW NOTIFIER below for details).
The procedures \fBTcl_ServiceAll\fR, \fBTcl_ServiceEvent\fR,
\fBTcl_GetServiceMode\fR, and \fBTcl_SetServiceMode\fR are provided
to help connect Tcl's event loop to an external event loop such as
Motif's.
.SH "NOTIFIER BASICS"
.VE
.PP
The easiest way to understand how the notifier works is to consider
what happens when \fBTcl_DoOneEvent\fR is called.
\fBTcl_DoOneEvent\fR is passed a \fIflags\fR argument that indicates
what sort of events it is OK to process and also whether or not to
block if no events are ready.  \fBTcl_DoOneEvent\fR does the following
things:
.IP [1]
Check the event queue to see if it contains any events that can
be serviced.  If so, service the first possible event, remove it
.VS 8.1
from the queue, and return.  It does this by calling
\fBTcl_ServiceEvent\fR and passing in the \fIflags\fR argument.
.VE
.IP [2]
Prepare to block for an event.  To do this, \fBTcl_DoOneEvent\fR
invokes a \fIsetup procedure\fR in each event source.
The event source will perform event-source specific initialization and
.VS 8.1
possibly call \fBTcl_SetMaxBlockTime\fR to limit how long
.VE
\fBTcl_WaitForEvent\fR will block if no new events occur.
.IP [3]
Call \fBTcl_WaitForEvent\fR.  This procedure is implemented differently
on different platforms;  it waits for an event to occur, based on the
information provided by the event sources.
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
when events of the desired type occur.  This is typically done in a
platform-dependent fashion.  For example, under Unix an event source
might call \fBTcl_CreateFileHandler\fR; under Windows it might
request notification with a Windows event.  For timer-driven event
sources such as timer events or any polled event, the event source
can call \fBTcl_SetMaxBlockTime\fR to force the application to wake
up after a specified time even if no events have occurred.
.VS
If no event source calls \fBTcl_SetMaxBlockTime\fR
then \fBTcl_WaitForEvent\fR will wait as long as necessary for an
event to occur; otherwise, it will only wait as long as the shortest
interval passed to \fBTcl_SetMaxBlockTime\fR by one of the event
sources.  If an event source knows that it already has events ready to
report, it can request a zero maximum block time.  For example, the
setup procedure for the X event source looks to see if there are







|







254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
when events of the desired type occur.  This is typically done in a
platform-dependent fashion.  For example, under Unix an event source
might call \fBTcl_CreateFileHandler\fR; under Windows it might
request notification with a Windows event.  For timer-driven event
sources such as timer events or any polled event, the event source
can call \fBTcl_SetMaxBlockTime\fR to force the application to wake
up after a specified time even if no events have occurred.
.VS 8.1
If no event source calls \fBTcl_SetMaxBlockTime\fR
then \fBTcl_WaitForEvent\fR will wait as long as necessary for an
event to occur; otherwise, it will only wait as long as the shortest
interval passed to \fBTcl_SetMaxBlockTime\fR by one of the event
sources.  If an event source knows that it already has events ready to
report, it can request a zero maximum block time.  For example, the
setup procedure for the X event source looks to see if there are
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
typedef struct Tcl_Time {
	long \fIsec\fR;
	long \fIusec\fR;
} Tcl_Time;
.CE
The \fIusec\fR field should be less than 1000000.
.PP
.VS
Information provided to \fBTcl_SetMaxBlockTime\fR
is only used for the next call to \fBTcl_WaitForEvent\fR; it is
discarded after \fBTcl_WaitForEvent\fR returns.
.VE
The next time an event wait is done each of the event sources'
setup procedures will be called again, and they can specify new
information for that event wait.
.PP
.VS
If the application uses an external event loop rather than
\fBTcl_DoOneEvent\fR, the event sources may need to call
\fBTcl_SetMaxBlockTime\fR at other times.  For example, if a new event
handler is registered that needs to poll for events, the event source
may call \fBTcl_SetMaxBlockTime\fR to set the block time to zero to
force the external event loop to call Tcl.  In this case,
\fBTcl_SetMaxBlockTime\fR invokes \fBTcl_SetTimer\fR with the shortest







|








|







278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
typedef struct Tcl_Time {
	long \fIsec\fR;
	long \fIusec\fR;
} Tcl_Time;
.CE
The \fIusec\fR field should be less than 1000000.
.PP
.VS 8.1
Information provided to \fBTcl_SetMaxBlockTime\fR
is only used for the next call to \fBTcl_WaitForEvent\fR; it is
discarded after \fBTcl_WaitForEvent\fR returns.
.VE
The next time an event wait is done each of the event sources'
setup procedures will be called again, and they can specify new
information for that event wait.
.PP
.VS 8.1
If the application uses an external event loop rather than
\fBTcl_DoOneEvent\fR, the event sources may need to call
\fBTcl_SetMaxBlockTime\fR at other times.  For example, if a new event
handler is registered that needs to poll for events, the event source
may call \fBTcl_SetMaxBlockTime\fR to set the block time to zero to
force the external event loop to call Tcl.  In this case,
\fBTcl_SetMaxBlockTime\fR invokes \fBTcl_SetTimer\fR with the shortest
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
events at the front whose position is \fBTCL_QUEUE_MARK\fR;  if so,
add the new event just after all other \fBTCL_QUEUE_MARK\fR events.
This value of \fIposition\fR is used to insert an ordered sequence of
events at the front of the queue, such as a series of
Enter and Leave events synthesized during a grab or ungrab operation
in Tk.
.PP
.VS
When it is time to handle an event from the queue (steps 1 and 4
above) \fBTcl_ServiceEvent\fR will invoke the \fIproc\fR specified
.VE
in the first queued \fBTcl_Event\fR structure.
\fIProc\fR must match the following prototype:
.CS
typedef int Tcl_EventProc(
	Tcl_Event *\fIevPtr\fR,
	int \fIflags\fR);
.CE
The first argument to \fIproc\fR is a pointer to the event, which will
be the same as the first argument to the \fBTcl_QueueEvent\fR call that
added the event to the queue.
The second argument to \fIproc\fR is the \fIflags\fR argument for the
.VS
current call to \fBTcl_ServiceEvent\fR;  this is used by the event source
.VE
to return immediately if its events are not relevant.
.PP
It is up to \fIproc\fR to handle the event, typically by invoking
one or more Tcl commands or C-level callbacks.
Once the event source has finished handling the event it returns 1
to indicate that the event can be removed from the queue.
If for some reason the event source decides that the event cannot
be handled at this time, it may return 0 to indicate that the event
.VS
should be deferred for processing later;  in this case \fBTcl_ServiceEvent\fR
.VE
will go on to the next event in the queue and attempt to service it.
There are several reasons why an event source might defer an event.
One possibility is that events of this type are excluded by the
\fIflags\fR argument.
For example, the file event source will always return 0 if the
\fBTCL_FILE_EVENTS\fR bit isn't set in \fIflags\fR.
Another example of deferring events happens in Tk if
\fBTk_RestrictEvents\fR has been invoked to defer certain kinds
of window events.
.PP
.VS
When \fIproc\fR returns 1, \fBTcl_ServiceEvent\fR will remove the
event from the event queue and free its storage.
Note that the storage for an event must be allocated by
the event source (using \fBTcl_Alloc\fR or the Tcl macro \fBckalloc\fR)
before calling \fBTcl_QueueEvent\fR, but it
will be freed by \fBTcl_ServiceEvent\fR, not by the event source.















.PP
\fBTcl_DeleteEvents\fR can be used to explicitly remove one or more
events from the event queue.  \fBTcl_DeleteEvents\fR calls \fIproc\fR
for each event in the queue, deleting those for with the procedure
returns 1.  Events for which the procedure returns 0 are left in the
queue.  \fIProc\fR should match the following prototype:
.CS
typedef int Tcl_EventDeleteProc(
	Tcl_Event *\fIevPtr\fR,
	ClientData \fIclientData\fR);
.CE
The \fIclientData\fR argument will be the same as the \fIclientData\fR
argument to \fBTcl_DeleteEvents\fR; it is typically used to point to
private information managed by the event source.  The \fIevPtr\fR will
point to the next event in the queue.





.VE

.SH "CREATING A NEW NOTIFIER"
.PP
The notifier consists of all the procedures described in this manual
entry, plus \fBTcl_DoOneEvent\fR and \fBTcl_Sleep\fR, which are
.VS
available on all platforms, and \fBTcl_CreateFileHandler\fR and
\fBTcl_DeleteFileHandler\fR, which are Unix-specific.  Most of these
procedures are generic, in that they are the same for all notifiers.
However, eight of the procedures are notifier-dependent:
\fBTcl_InitNotifier\fR, \fBTcl_AlertNotifier\fR, \fBTcl_FinalizeNotifier\fR, 
\fBTcl_SetTimer\fR, \fBTcl_Sleep\fR, \fBTcl_WaitForEvent\fR,
\fBTcl_CreateFileHandler\fR and \fBTcl_DeleteFileHandler\fR.  To
support a new platform or to integrate Tcl with an
application-specific event loop, you must write new versions of these
procedures.






.PP
\fBTcl_WaitForEvent\fR is the lowest-level procedure in the notifier;
it is responsible for waiting for an ``interesting'' event to occur or
for a given time to elapse.  Before \fBTcl_WaitForEvent\fR is invoked,
each of the event sources' setup procedure will have been invoked.
The \fItimePtr\fR argument to
\fBTcl_WaitForEvent\fR gives the maximum time to block for an event,







|














|










|












|






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>















>
>
>
>
>






|










>
>
>
>
>
>







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
events at the front whose position is \fBTCL_QUEUE_MARK\fR;  if so,
add the new event just after all other \fBTCL_QUEUE_MARK\fR events.
This value of \fIposition\fR is used to insert an ordered sequence of
events at the front of the queue, such as a series of
Enter and Leave events synthesized during a grab or ungrab operation
in Tk.
.PP
.VS 8.1
When it is time to handle an event from the queue (steps 1 and 4
above) \fBTcl_ServiceEvent\fR will invoke the \fIproc\fR specified
.VE
in the first queued \fBTcl_Event\fR structure.
\fIProc\fR must match the following prototype:
.CS
typedef int Tcl_EventProc(
	Tcl_Event *\fIevPtr\fR,
	int \fIflags\fR);
.CE
The first argument to \fIproc\fR is a pointer to the event, which will
be the same as the first argument to the \fBTcl_QueueEvent\fR call that
added the event to the queue.
The second argument to \fIproc\fR is the \fIflags\fR argument for the
.VS 8.1
current call to \fBTcl_ServiceEvent\fR;  this is used by the event source
.VE
to return immediately if its events are not relevant.
.PP
It is up to \fIproc\fR to handle the event, typically by invoking
one or more Tcl commands or C-level callbacks.
Once the event source has finished handling the event it returns 1
to indicate that the event can be removed from the queue.
If for some reason the event source decides that the event cannot
be handled at this time, it may return 0 to indicate that the event
.VS 8.1
should be deferred for processing later;  in this case \fBTcl_ServiceEvent\fR
.VE
will go on to the next event in the queue and attempt to service it.
There are several reasons why an event source might defer an event.
One possibility is that events of this type are excluded by the
\fIflags\fR argument.
For example, the file event source will always return 0 if the
\fBTCL_FILE_EVENTS\fR bit isn't set in \fIflags\fR.
Another example of deferring events happens in Tk if
\fBTk_RestrictEvents\fR has been invoked to defer certain kinds
of window events.
.PP
.VS 8.1
When \fIproc\fR returns 1, \fBTcl_ServiceEvent\fR will remove the
event from the event queue and free its storage.
Note that the storage for an event must be allocated by
the event source (using \fBTcl_Alloc\fR or the Tcl macro \fBckalloc\fR)
before calling \fBTcl_QueueEvent\fR, but it
will be freed by \fBTcl_ServiceEvent\fR, not by the event source.
.PP
Threaded applications work in a
similar manner, except that there is a separate event queue for
each thread containing a Tcl interpreter.
Calling \fBTcl_QueueEvent\fR in a multithreaded application adds
an event to the current thread's queue.
To add an event to another thread's queue, use \fBTcl_ThreadQueueEvent\fR.
\fBTcl_ThreadQueueEvent\fR accepts as an argument a Tcl_ThreadId argument,
which uniquely identifies a thread in a Tcl application.  To obtain the
Tcl_ThreadID for the current thread, use the \fBTcl_GetCurrentThread\fR
procedure.  (A thread would then need to pass this identifier to other
threads for those threads to be able to add events to its queue.)
After adding an event to another thread's queue, you then typically
need to call \fBTcl_ThreadAlert\fR to "wake up" that thread's notifier to
alert it to the new event.
.PP
\fBTcl_DeleteEvents\fR can be used to explicitly remove one or more
events from the event queue.  \fBTcl_DeleteEvents\fR calls \fIproc\fR
for each event in the queue, deleting those for with the procedure
returns 1.  Events for which the procedure returns 0 are left in the
queue.  \fIProc\fR should match the following prototype:
.CS
typedef int Tcl_EventDeleteProc(
	Tcl_Event *\fIevPtr\fR,
	ClientData \fIclientData\fR);
.CE
The \fIclientData\fR argument will be the same as the \fIclientData\fR
argument to \fBTcl_DeleteEvents\fR; it is typically used to point to
private information managed by the event source.  The \fIevPtr\fR will
point to the next event in the queue.
.PP
\fBTcl_DeleteEventSource\fR deletes an event source.  The \fIsetupProc\fR,
\fIcheckProc\fR, and \fIclientData\fR arguments must exactly match those
provided to the \fBTcl_CreateEventSource\fR for the event source to be deleted.
If no such source exists, \fBTcl_DeleteEventSource\fR has no effect.
.VE

.SH "CREATING A NEW NOTIFIER"
.PP
The notifier consists of all the procedures described in this manual
entry, plus \fBTcl_DoOneEvent\fR and \fBTcl_Sleep\fR, which are
.VS 8.1
available on all platforms, and \fBTcl_CreateFileHandler\fR and
\fBTcl_DeleteFileHandler\fR, which are Unix-specific.  Most of these
procedures are generic, in that they are the same for all notifiers.
However, eight of the procedures are notifier-dependent:
\fBTcl_InitNotifier\fR, \fBTcl_AlertNotifier\fR, \fBTcl_FinalizeNotifier\fR, 
\fBTcl_SetTimer\fR, \fBTcl_Sleep\fR, \fBTcl_WaitForEvent\fR,
\fBTcl_CreateFileHandler\fR and \fBTcl_DeleteFileHandler\fR.  To
support a new platform or to integrate Tcl with an
application-specific event loop, you must write new versions of these
procedures.
.PP
\fBTcl_InitNotifier\fR initializes the notifier state and returns
a handle to the notifier state.  Tcl calls this
procedure when intializing a Tcl interpreter.  Similarly,
\fBTcl_FinalizeNotifier\fR shuts down the notifier, and is
called by \Tcl_Finalize\fR when shutting down a Tcl interpreter.
.PP
\fBTcl_WaitForEvent\fR is the lowest-level procedure in the notifier;
it is responsible for waiting for an ``interesting'' event to occur or
for a given time to elapse.  Before \fBTcl_WaitForEvent\fR is invoked,
each of the event sources' setup procedure will have been invoked.
The \fItimePtr\fR argument to
\fBTcl_WaitForEvent\fR gives the maximum time to block for an event,
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
additional events to process (e.g. it returned because the time
elapsed).  Finally, a return value of \-1 means that the event loop is
no longer operational and the application should probably unwind and
terminate.  Under Windows this happens when a WM_QUIT message is received;
under Unix it happens when \fBTcl_WaitForEvent\fR would have waited
forever because there were no active event sources and the timeout was
infinite.





.PP
If the notifier will be used with an external event loop, then it must
also support the \fBTcl_SetTimer\fR interface.  \fBTcl_SetTimer\fR is
invoked by \fBTcl_SetMaxBlockTime\fR whenever the maximum blocking
time has been reduced.  \fBTcl_SetTimer\fR should arrange for the
external event loop to invoke \fBTcl_ServiceAll\fR after the specified
interval even if no events have occurred.  This interface is needed
because \fBTcl_WaitForEvent\fR isn't invoked when there is an external
event loop.  If the
notifier will only be used from \fBTcl_DoOneEvent\fR, then
\fBTcl_SetTimer\fR need not do anything.
.PP
On Unix systems, the file event source also needs support from the
notifier.  The file event source consists of the
\fBTcl_CreateFileHandler\fR and \fBTcl_DeleteFileHandler\fR
procedures, which are described elsewhere.

.PP
The \fBTcl_Sleep\fR and \fBTcl_DoOneEvent\fR interfaces are described
elsewhere.
.PP
The easiest way to create a new notifier is to look at the code
for an existing notifier, such as the files \fBunix/tclUnixNotfy.c\fR
or \fBwin/tclWinNotify.c\fR in the Tcl source distribution.

.SH "EXTERNAL EVENT LOOPS"
.PP







>
>
>
>
>















|
>


|







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
additional events to process (e.g. it returned because the time
elapsed).  Finally, a return value of \-1 means that the event loop is
no longer operational and the application should probably unwind and
terminate.  Under Windows this happens when a WM_QUIT message is received;
under Unix it happens when \fBTcl_WaitForEvent\fR would have waited
forever because there were no active event sources and the timeout was
infinite.
.PP
\fBTcl_AlertNotifier\fR is used in multithreaded applications to allow
any thread to "wake up" the notifier to alert it to new events on its
queue.  \fBTcl_AlertNotifier\fR requires as an argument the notifier
handle returned by \fBTcl_InitNotifier\fR.
.PP
If the notifier will be used with an external event loop, then it must
also support the \fBTcl_SetTimer\fR interface.  \fBTcl_SetTimer\fR is
invoked by \fBTcl_SetMaxBlockTime\fR whenever the maximum blocking
time has been reduced.  \fBTcl_SetTimer\fR should arrange for the
external event loop to invoke \fBTcl_ServiceAll\fR after the specified
interval even if no events have occurred.  This interface is needed
because \fBTcl_WaitForEvent\fR isn't invoked when there is an external
event loop.  If the
notifier will only be used from \fBTcl_DoOneEvent\fR, then
\fBTcl_SetTimer\fR need not do anything.
.PP
On Unix systems, the file event source also needs support from the
notifier.  The file event source consists of the
\fBTcl_CreateFileHandler\fR and \fBTcl_DeleteFileHandler\fR
procedures, which are described in the \fBTcl_CreateFileHandler\fR
manual page.
.PP
The \fBTcl_Sleep\fR and \fBTcl_DoOneEvent\fR interfaces are described
in their respective manual pages.
.PP
The easiest way to create a new notifier is to look at the code
for an existing notifier, such as the files \fBunix/tclUnixNotfy.c\fR
or \fBwin/tclWinNotify.c\fR in the Tcl source distribution.

.SH "EXTERNAL EVENT LOOPS"
.PP
542
543
544
545
546
547
548
549


550
551
events.  If \fBTcl_SetServiceMode\fR is passed \fBTCL_SERVICE_ALL\fR,
then calls to \fBTcl_ServiceAll\fR will behave normally.
\fBTcl_SetServiceMode\fR returns the previous value of the service
mode, which should be restored when the recursive loop exits.
\fBTcl_GetServiceMode\fR returns the current value of the service
mode.
.VE



.SH KEYWORDS
event, notifier, event queue, event sources, file events, timer, idle, service mode







|
>
>

|
591
592
593
594
595
596
597
598
599
600
601
602
events.  If \fBTcl_SetServiceMode\fR is passed \fBTCL_SERVICE_ALL\fR,
then calls to \fBTcl_ServiceAll\fR will behave normally.
\fBTcl_SetServiceMode\fR returns the previous value of the service
mode, which should be restored when the recursive loop exits.
\fBTcl_GetServiceMode\fR returns the current value of the service
mode.
.VE
.SH "SEE ALSO"
\fBTcl_CreateFileHandler\fR, \fBTcl_DeleteFileHandler\fR, \fBTcl_Sleep\fR,
\fBTcl_DoOneEvent\fR, \fBThreads.3\fR
.SH KEYWORDS
event, notifier, event queue, event sources, file events, timer, idle, service mode, threads
Changes to doc/OpenFileChnl.3.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'\"
'\" Copyright (c) 1996-1997 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
'\" RCS: @(#) $Id: OpenFileChnl.3,v 1.3 1999/04/16 00:46:32 stanton Exp $
.so man.macros
.TH Tcl_OpenFileChannel 3 8.1 Tcl "Tcl Library Procedures"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
Tcl_OpenFileChannel, Tcl_OpenCommandChannel, Tcl_MakeFileChannel, Tcl_GetChannel, Tcl_RegisterChannel, Tcl_UnregisterChannel, Tcl_Close, Tcl_ReadChars, Tcl_Read, Tcl_GetsObj, Tcl_Gets, Tcl_WriteObj, Tcl_WriteChars, Tcl_Write, Tcl_Flush, Tcl_Seek, Tcl_Tell, Tcl_GetChannelOption, Tcl_SetChannelOption, Tcl_Eof, Tcl_InputBlocked, Tcl_InputBuffered,  \- buffered I/O facilities using channels
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
typedef ... Tcl_Channel;
.sp
Tcl_Channel






|





|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'\"
'\" Copyright (c) 1996-1997 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
'\" RCS: @(#) $Id: OpenFileChnl.3,v 1.3.4.1 1999/04/29 02:06:54 stanton Exp $
.so man.macros
.TH Tcl_OpenFileChannel 3 8.1 Tcl "Tcl Library Procedures"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
Tcl_OpenFileChannel, Tcl_OpenCommandChannel, Tcl_MakeFileChannel, Tcl_GetChannel, Tcl_RegisterChannel, Tcl_UnregisterChannel, Tcl_Close, Tcl_ReadChars, Tcl_Read, Tcl_GetsObj, Tcl_Gets, Tcl_WriteObj, Tcl_WriteChars, Tcl_Write, Tcl_Flush, Tcl_Seek, Tcl_Tell, Tcl_GetChannelOption, Tcl_SetChannelOption, Tcl_Eof, Tcl_InputBlocked, Tcl_InputBuffered \- buffered I/O facilities using channels
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
typedef ... Tcl_Channel;
.sp
Tcl_Channel
Changes to doc/Thread.3.
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
'\"

'\" Copyright (c) 1998 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" RCS: @(#) $Id: Thread.3,v 1.4 1999/04/21 21:50:22 rjohnson Exp $
'\" 
.so man.macros
.TH Tcl_ConditionNotify 3 "8.1" Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_ConditionNotify, Tcl_ConditionWait, Tcl_GetThreadData, Tcl_MutexLock, Tcl_MutexUnlock \- thread synchronization support.
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
void
\fBTcl_ConditionNotify\fR(\fIcondPtr\fR)
.sp
void
\fBTcl_ConditionWait\fR(\fIcondPtr, mutexPtr, timePtr\fR)
.sp
Tcl_ThreadId
\fBTcl_GetCurrentThread\fR()
.sp
VOID *
\fBTcl_GetThreadData\fR(\fIkeyPtr, size\fR)
.sp
void
\fBTcl_MutexLock\fR(\fImutexPtr\fR)
.sp
void
\fBTcl_MutexUnlock\fR(\fImutexPtr\fR)
.sp
\fBTcl_ThreadAlert\fR(\fIthreadId\fR)
.sp
\fBTcl_ThreadQueueEvent\fR(\fIthreadId, evPtr, position\fR)
.SH ARGUMENTS
.AS Tcl_ThreadDataKey *keyPtr
.AP Tcl_Condition *condPtr in
A condition variable, which must be associated with a mutex lock.
.AP Tcl_Condition *mutexPtr in
A mutex lock.
.AP Tcl_Time *timePtr in
A time limit on the condition wait.  NULL to wait forever.
Note that a polling value of 0 seconds doesn't make much sense.
.AP Tcl_ThreadDataKey *keyPtr in
This identifies a block of thread local storage.  The key should be
static and process-wide, yet each thread will end up associating
a different block of storage with this key.
.AP int *size in
The size of the thread local storage block.  This amount of data
is allocated and initialized to zero the first time each thread
calls \fBTcl_GetThreadData\fR.
.BE






.SH DESCRIPTION






.PP






















A mutex is a lock that is used to serialize all threads through a piece
of code by calling \fBTcl_MutexLock\fR and \fBTcl_MutexUnlock\fR.
If one thread holds a mutex, any other thread calling \fBTcl_MutexLock\fR will
block until \fBTcl_MutexUnlock\fR is called.
.VS
The result of locking a mutex twice from the same thread is undefined.
On some platforms it will result in a deadlock.

>





|


|


|










<
<
<
|







<
<
<
<


















|
>
>
>
>
>
|
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
'\"
'\" Copyright (c) 1999 Scriptics Corporation
'\" Copyright (c) 1998 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" RCS: @(#) $Id: Thread.3,v 1.4.2.2 1999/04/29 02:06:54 stanton Exp $
'\" 
.so man.macros
.TH Threads 3 "8.1" Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_ConditionNotify, Tcl_ConditionWait, Tcl_GetThreadData, Tcl_MutexLock, Tcl_MutexUnlock \- Tcl thread support.
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
void
\fBTcl_ConditionNotify\fR(\fIcondPtr\fR)
.sp
void
\fBTcl_ConditionWait\fR(\fIcondPtr, mutexPtr, timePtr\fR)
.sp



Void *
\fBTcl_GetThreadData\fR(\fIkeyPtr, size\fR)
.sp
void
\fBTcl_MutexLock\fR(\fImutexPtr\fR)
.sp
void
\fBTcl_MutexUnlock\fR(\fImutexPtr\fR)




.SH ARGUMENTS
.AS Tcl_ThreadDataKey *keyPtr
.AP Tcl_Condition *condPtr in
A condition variable, which must be associated with a mutex lock.
.AP Tcl_Condition *mutexPtr in
A mutex lock.
.AP Tcl_Time *timePtr in
A time limit on the condition wait.  NULL to wait forever.
Note that a polling value of 0 seconds doesn't make much sense.
.AP Tcl_ThreadDataKey *keyPtr in
This identifies a block of thread local storage.  The key should be
static and process-wide, yet each thread will end up associating
a different block of storage with this key.
.AP int *size in
The size of the thread local storage block.  This amount of data
is allocated and initialized to zero the first time each thread
calls \fBTcl_GetThreadData\fR.
.BE
.SH INTRODUCTION
Beginning with the 8.1 release, the Tcl core is thread safe, which
allows you to incorporate Tcl into multithreaded applications without
customizing the Tcl core.  To enable Tcl multithreading support,
you must include the \fB--enable-threads\fR option to \fBconfigure\fR
when you configure and compile your Tcl core.
.PP
An important contstraint of the Tcl threads implementation is that
\fIonly the thread that created a Tcl interpreter can use that
interpreter\fR.  In other words, multiple threads can not access
the same Tcl interpreter.  (However, as was the case in previous
releases, a single thread can safely create and use multiple
interpreters.)
.PP
Tcl provides no special API for creating
threads.  When writing multithreaded applications incorporating Tcl,
use the standard POSIX threads APIs on Unix systems and the standard
Win32 threads APIs on Windows systems.
.PP
Tcl does provide \fBTcl_ExitThread\fR and \fBTcl_FinalizeThread\fR
for terminating threads and invoking optional per-thread exit
handlers.  See the \fBTcl_Exit\fR page for more information on these
procedures.
.PP
Tcl provides \fBTcl_ThreadQueueEvent\fR and \fBTcl_ThreadAlert\fR
for handling event queueing in multithreaded applications.  See
the \fBNotifier\fR manual page for more information on these procedures.
.PP
In this release, the Tcl language itself provides no support for
creating multithreaded scripts (for example, scripts that could spawn
a Tcl interpreter in a separate thread).  If you need to add this
feature at this time, see the \fItclThreadTest.c\fR
file in the Tcl source distribution for an experimental implementation
of a Tcl "Thread" package implementing thread creation and management
commands at the script level.
.SH DESCRIPTION
A mutex is a lock that is used to serialize all threads through a piece
of code by calling \fBTcl_MutexLock\fR and \fBTcl_MutexUnlock\fR.
If one thread holds a mutex, any other thread calling \fBTcl_MutexLock\fR will
block until \fBTcl_MutexUnlock\fR is called.
.VS
The result of locking a mutex twice from the same thread is undefined.
On some platforms it will result in a deadlock.
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
The implementation of \fBTcl_ConditionWait\fR automatically locks
the mutex before returning.
.PP
The caller of \fBTcl_ConditionWait\fR should be prepared for spurious
notifications by calling \fBTcl_ConditionWait\fR within a while loop
that tests some invariant.
.PP
The \fBTcl_GetCurrentThread\fR call returns the thread Id of the
thread in which the call is made.  The thread Id can be used in calls
to \fBTcl_ThreadQueueEvent\fR and \fBTcl_ThreadAlert\fR.  These
procedures are essentially mutex-protected vesions of
\fBTcl_AlertNotifier\fR and \fBTcl_QueueEvent\fR, respectively.  See
the manual entry for \fBNotifier\fR for more details.
.PP
The \fBTcl_GetThreadData\fR call returns a pointer to a block of
thread-private data.  Its argument is a key that is shared by all threads
and a size for the block of storage.  The storage is automatically 
allocated and initialized to all zeros the first time each thread asks for it.
The storage is automatically deallocated by \fBTcl_FinalizeThread\fR.
.SH INITIALIZATION
.PP
.PP
All of these synchronization objects are self initializing.
They are implemented as opaque pointers that should be NULL
upon first use.
The mutexes and condition variables are
cleaned up by process exit handlers.  Thread local storage is
reclaimed during \fBTcl_FinalizeThread\fR.
.SH CREATING THREADS
The API to create threads is not finalized at this time.
There are private facilities to create threads that contain a new
Tcl interpreter, and to send scripts among threads.
Dive into tclThreadTest.c and tclThread.c for examples.




.SH KEYWORDS
thread, mutex, condition variable, thread local storage







<
<
<
<
<
<
<






<












>
>
>
>


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
The implementation of \fBTcl_ConditionWait\fR automatically locks
the mutex before returning.
.PP
The caller of \fBTcl_ConditionWait\fR should be prepared for spurious
notifications by calling \fBTcl_ConditionWait\fR within a while loop
that tests some invariant.
.PP







The \fBTcl_GetThreadData\fR call returns a pointer to a block of
thread-private data.  Its argument is a key that is shared by all threads
and a size for the block of storage.  The storage is automatically 
allocated and initialized to all zeros the first time each thread asks for it.
The storage is automatically deallocated by \fBTcl_FinalizeThread\fR.
.SH INITIALIZATION

.PP
All of these synchronization objects are self initializing.
They are implemented as opaque pointers that should be NULL
upon first use.
The mutexes and condition variables are
cleaned up by process exit handlers.  Thread local storage is
reclaimed during \fBTcl_FinalizeThread\fR.
.SH CREATING THREADS
The API to create threads is not finalized at this time.
There are private facilities to create threads that contain a new
Tcl interpreter, and to send scripts among threads.
Dive into tclThreadTest.c and tclThread.c for examples.
.SH "SEE ALSO"
Tcl_GetCurrentThread, Tcl_ThreadQueueEvent, Tcl_ThreadAlert,
Tcl_ExitThread, Tcl_FinalizeThread,
Tcl_CreateThreadExitHandler, Tcl_DeleteThreadExitHandler
.SH KEYWORDS
thread, mutex, condition variable, thread local storage
Changes to doc/Utf.3.
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
'\"
'\" Copyright (c) 1997 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" RCS: @(#) $Id: Utf.3,v 1.2 1999/04/16 00:46:34 stanton Exp $
'\" 
.so man.macros
.TH Utf 3 "8.1" Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_UniChar, Tcl_UniCharToUtf, Tcl_UtfToUniChar, Tcl_UtfCharComplete, Tcl_NumUtfChars, Tcl_UtfFindFirst, Tcl_UtfFindLast, Tcl_UtfNext, Tcl_UtfPrev, Tcl_UniCharAtIndex, Tcl_UtfAtIndex, Tcl_UtfBackslash \- routines for manipulating UTF-8 strings.
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
typedef ... Tcl_UniChar;
.sp
int
\fBTcl_UniCharToUtf\fR(\fIch, buf\fR)
.sp
int
\fBTcl_UtfToUniChar\fR(\fIsrc, chPtr\fR)
.sp












int
\fBTcl_UtfCharComplete\fR(\fIsrc, len\fR)
.sp
int 
\fBTcl_NumUtfChars\fR(\fIsrc, len\fR)
.sp
char *






|





|












>
>
>
>
>
>
>
>
>
>
>
>







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
'\"
'\" Copyright (c) 1997 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" RCS: @(#) $Id: Utf.3,v 1.2.4.2 1999/04/29 02:06:54 stanton Exp $
'\" 
.so man.macros
.TH Utf 3 "8.1" Tcl "Tcl Library Procedures"
.BS
.SH NAME
Tcl_UniChar, Tcl_UniCharToUtf, Tcl_UtfToUniChar, Tcl_UniCharToUtfDString, Tcl_UtfToUniCharDString, Tcl_UniCharLen, Tcl_UniCharNcmp, Tcl_UtfCharComplete, Tcl_NumUtfChars, Tcl_UtfFindFirst, Tcl_UtfFindLast, Tcl_UtfNext, Tcl_UtfPrev, Tcl_UniCharAtIndex, Tcl_UtfAtIndex, Tcl_UtfBackslash \- routines for manipulating UTF-8 strings.
.SH SYNOPSIS
.nf
\fB#include <tcl.h>\fR
.sp
typedef ... Tcl_UniChar;
.sp
int
\fBTcl_UniCharToUtf\fR(\fIch, buf\fR)
.sp
int
\fBTcl_UtfToUniChar\fR(\fIsrc, chPtr\fR)
.sp
char *
\fBTcl_UniCharToUtfDString\fR(\fIuniStr, numChars, dstPtr\fR)
.sp
Tcl_UniChar *
\fBTcl_UtfToUniCharDString\fR(\fIsrc, len, dstPtr\fR)
.sp
int
\fBTcl_UniCharLen\fR(\fIuniStr\fR)
.sp
int
\fBTcl_UniCharNcmp\fR(\fIuniStr, uniStr, num\fR)
.sp
int
\fBTcl_UtfCharComplete\fR(\fIsrc, len\fR)
.sp
int 
\fBTcl_NumUtfChars\fR(\fIsrc, len\fR)
.sp
char *
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
.sp
char *
\fBTcl_UtfAtIndex\fR(\fIsrc, index\fR)
.sp
int
\fBTcl_UtfBackslash\fR(\fIsrc, readPtr, dst\fR)
.SH ARGUMENTS
.AS "CONST char" *chPtr out
.AP char *buf out
Buffer in which the UTF-8 representation of the Tcl_UniChar is stored.  At most
TCL_UTF_MAX bytes are stored in the buffer.
.AP int ch in
The Tcl_UniChar to be converted or examined.
.AP Tcl_UniChar *chPtr out
Filled with the Tcl_UniChar represented by the head of the UTF-8 string.
.AP "CONST char" *src in
Pointer to a UTF-8 string.


.AP int len in
The length of the UTF-8 string in bytes (not UTF-8 characters).  If
negative, all bytes up to the first null byte are used.







.AP "CONST char" *start in
Pointer to the beginning of a UTF-8 string.
.AP int index in
The index of a character (not byte) in the UTF-8 string.
.AP int *readPtr out
If non-NULL, filled with the number of bytes in the backslash sequence, 
including the backslash character.







|









>
>



>
>
>
>
>
>
>







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
.sp
char *
\fBTcl_UtfAtIndex\fR(\fIsrc, index\fR)
.sp
int
\fBTcl_UtfBackslash\fR(\fIsrc, readPtr, dst\fR)
.SH ARGUMENTS
.AS "CONST Tcl_UniChar" numChars in/out
.AP char *buf out
Buffer in which the UTF-8 representation of the Tcl_UniChar is stored.  At most
TCL_UTF_MAX bytes are stored in the buffer.
.AP int ch in
The Tcl_UniChar to be converted or examined.
.AP Tcl_UniChar *chPtr out
Filled with the Tcl_UniChar represented by the head of the UTF-8 string.
.AP "CONST char" *src in
Pointer to a UTF-8 string.
.AP "CONST Tcl_UniChar" *uniStr in
A NULL-terminated Unicode string.
.AP int len in
The length of the UTF-8 string in bytes (not UTF-8 characters).  If
negative, all bytes up to the first null byte are used.
.AP int numChars in
The length of the Unicode string in characters.  Must be greater than or
equal to 0.
.AP "Tcl_DString" *dstPtr in/out
A pointer to a previously-initialized \fBTcl_DString\fR.
.AP size_t n in
The number of Unicode characters to compare in \fBTcl_UniCharNcmp\fR.
.AP "CONST char" *start in
Pointer to the beginning of a UTF-8 string.
.AP int index in
The index of a character (not byte) in the UTF-8 string.
.AP int *readPtr out
If non-NULL, filled with the number of bytes in the backslash sequence, 
including the backslash character.
95
96
97
98
99
100
101






























102
103
104
105
106
107
108
number of bytes read from \fIsrc\fR..  The caller must ensure that the
source buffer is long enough such that this routine does not run off the
end and dereference non-existent or random memory; if the source buffer
is known to be null terminated, this will not happen.  If the input is
not in proper UTF-8 format, \fBTcl_UtfToUniChar\fR will store the first
byte of \fIsrc\fR in \fI*chPtr\fR as a Tcl_UniChar between 0x0000 and
0x00ff and return 1.  






























.PP
\fBTcl_UtfCharComplete\fR returns 1 if the source UTF-8 string \fIsrc\fR
of length \fIlen\fR bytes is long enough to be decoded by
\fBTcl_UtfToUniChar\fR, or 0 otherwise.  This function does not guarantee
that the UTF-8 string is properly formed.  This routine is used by
procedures that are operating on a byte at a time and need to know if a
full Tcl_UniChar has been seen.







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
number of bytes read from \fIsrc\fR..  The caller must ensure that the
source buffer is long enough such that this routine does not run off the
end and dereference non-existent or random memory; if the source buffer
is known to be null terminated, this will not happen.  If the input is
not in proper UTF-8 format, \fBTcl_UtfToUniChar\fR will store the first
byte of \fIsrc\fR in \fI*chPtr\fR as a Tcl_UniChar between 0x0000 and
0x00ff and return 1.  
.PP
\fBTcl_UniCharToUtfDString\fR converts the given Unicode string
to UTF-8, storing the result in a previously-initialized \fBTcl_DString\fR.
You must specify the length of the given Unicode string.
The return value is a pointer to the UTF-8 representation of the
Unicode string.  Storage for the return value is appended to the
end of the \fBTcl_DString\fR.
.PP
\fBTcl_UtfToUniCharDString\fR coverts the given UTF-8 string to Unicode,
storing the result in the previously-initialized \fBTcl_Dstring\fR.
you may either specify the length of the given UTF-8 string or "-1",
in which case \fBTcl_UtfToUniCharDString\fR uses \fBstrlen\fR to
calculate the length.  The return value is a pointer to the Unicode
representation of the UTF-8 string.  Storage for the return value
is appended to the end of the \fBTcl_DString\fR.  The Unicode string
is terminated with a Unicode NULL character.
.PP
\fBTcl_UniCharLen\fR corresponds to \fBstrlen\fR for Unicode
characters.  It accepts a NULL-terminated Unicode string and returns
the number of Unicode characters (not bytes) in that string.
.PP
\fBTcl_UniCharNcmp\fR corresponds to \fBstrncmp\fR for Unicode
characters.  It accepts two NULL-terminated Unicode strings
and the number of characters to compare.  (Both strings are
assumed to be at least \fIlen\fR characters long.)
\fBTcl_UniCharNcmp\fR compares the two strings character-by-character
according to the Unicode character ordering.  It returns an integer
greater than, equal to,
or less than 0 if the first string is greater than, equal to, or
less than the second string respectively.
.PP
\fBTcl_UtfCharComplete\fR returns 1 if the source UTF-8 string \fIsrc\fR
of length \fIlen\fR bytes is long enough to be decoded by
\fBTcl_UtfToUniChar\fR, or 0 otherwise.  This function does not guarantee
that the UTF-8 string is properly formed.  This routine is used by
procedures that are operating on a byte at a time and need to know if a
full Tcl_UniChar has been seen.
Changes to doc/msgcat.n.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.so man.macros
.TH "msgcat" n 8.1 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
msgcat \- Tcl message catalog
.SH SYNOPSIS
\fB::msgcat::mc src-string\fR
.sp
\fB::msgcat::mclocale \fR?\fInewLocale\fR?
.sp
\fB::msgcat::mcpreferences\fR
.sp
\fB::msgcat::mcload \fIdirname\fR
.sp







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.so man.macros
.TH "msgcat" n 8.1 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
msgcat \- Tcl message catalog
.SH SYNOPSIS
\fB::msgcat::mc \fIsrc-string\fR
.sp
\fB::msgcat::mclocale \fR?\fInewLocale\fR?
.sp
\fB::msgcat::mcpreferences\fR
.sp
\fB::msgcat::mcload \fIdirname\fR
.sp
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
.PP
Use of the message catalog is optional by any application
or package, but is encouraged if the application or package
wishes to be enabled for multi-lingual applications.

.SH COMMANDS
.TP
\fB::msgcat::mc src-string\fR
Returns a translation of \fIsrc-string\fR according to the
user's current locale.  If no translation string
exists, \fB::msgcat::mcunknown\fR is called and the string
returned from \fB::msgcat::mcunknown\fR is returned.
.PP
\fB::msgcat::mc\fR is the main function used to localize an
application.  Instead of using an English string directly, an
applicaton can pass the English string through \fB::msgcat::mc\fR and
use the result.  If an application is written for a single language in
this fashion, then it is easy to add support for additional languages
later simply by defining new message catalog entries.
.TP
\fB::msgcat::mclocale \fR?\fInewLocale\fR?  
This function sets the locale to \fInewLocale\fR.  If \fInewLocale\fR
is omitted, the current locale is returned, otherwise the new locale

is returned.  The initial locale defaults to the locale specified in
the user's environment.  See \fBLOCALE AND SUBLOCALE SPECIFICATION\fR
below for a description of the locale string format.
.TP
\fB::msgcat::mcpreferences\fR
Returns an ordered list of the locales preferred by
the user, based on the user's language specification.
The list is ordered from most specific to least







|














|
>
|







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
.PP
Use of the message catalog is optional by any application
or package, but is encouraged if the application or package
wishes to be enabled for multi-lingual applications.

.SH COMMANDS
.TP
\fB::msgcat::mc \fIsrc-string\fR
Returns a translation of \fIsrc-string\fR according to the
user's current locale.  If no translation string
exists, \fB::msgcat::mcunknown\fR is called and the string
returned from \fB::msgcat::mcunknown\fR is returned.
.PP
\fB::msgcat::mc\fR is the main function used to localize an
application.  Instead of using an English string directly, an
applicaton can pass the English string through \fB::msgcat::mc\fR and
use the result.  If an application is written for a single language in
this fashion, then it is easy to add support for additional languages
later simply by defining new message catalog entries.
.TP
\fB::msgcat::mclocale \fR?\fInewLocale\fR?  
This function sets the locale to \fInewLocale\fR.  If \fInewLocale\fR
is omitted, the current locale is returned, otherwise the current locale
is set to \fInewLocale\fR.
The initial locale defaults to the locale specified in
the user's environment.  See \fBLOCALE AND SUBLOCALE SPECIFICATION\fR
below for a description of the locale string format.
.TP
\fB::msgcat::mcpreferences\fR
Returns an ordered list of the locales preferred by
the user, based on the user's language specification.
The list is ordered from most specific to least
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
The number of message files which matched the specification
and were loaded is returned.
.TP
\fB::msgcat::mcset \fIlocale src-string \fR?\fItranslate-string\fR?
Sets the translation for \fIsrc-string\fR to \fItranslate-string\fR
in the specified \fIlocale\fR.  If \fItranslate-string\fR is not
specified, \fIsrc-string\fR is used for both.  The function
return \fItranslate-string\fR.
.TP
\fB::msgcat::mcunknown \fIlocale src-string\fR
This routine is called by \fB::msgcat::mc\fR in the case when
a translation for \fIsrc-string\fR is not defined in the
current locale.  The default action is to return
\fIsrc-string\fR.  This procedure can be redefined by the
application, for example to log error messages for each unknown
string.  The \fB::msgcat::mcunknown\fB procedure is invoked at the
same stack context as the call to \fB::msgcat::mc\fR.  The return vaue
of \fB::msgcat::mcunknown\fB is used as the return vaue for the call
to \fB::msgcat::mc\fR.  

.SH "LOCALE AND SUBLOCALE SPECIFICATION"
.PP
The locale is specified by a locale string.
The locale string consists of
a language code, an optional country code, and an optional







|







|

|







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 number of message files which matched the specification
and were loaded is returned.
.TP
\fB::msgcat::mcset \fIlocale src-string \fR?\fItranslate-string\fR?
Sets the translation for \fIsrc-string\fR to \fItranslate-string\fR
in the specified \fIlocale\fR.  If \fItranslate-string\fR is not
specified, \fIsrc-string\fR is used for both.  The function
returns \fItranslate-string\fR.
.TP
\fB::msgcat::mcunknown \fIlocale src-string\fR
This routine is called by \fB::msgcat::mc\fR in the case when
a translation for \fIsrc-string\fR is not defined in the
current locale.  The default action is to return
\fIsrc-string\fR.  This procedure can be redefined by the
application, for example to log error messages for each unknown
string.  The \fB::msgcat::mcunknown\fR procedure is invoked at the
same stack context as the call to \fB::msgcat::mc\fR.  The return vaue
of \fB::msgcat::mcunknown\fR is used as the return vaue for the call
to \fB::msgcat::mc\fR.  

.SH "LOCALE AND SUBLOCALE SPECIFICATION"
.PP
The locale is specified by a locale string.
The locale string consists of
a language code, an optional country code, and an optional
Changes to doc/regexp.n.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1998 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" RCS: @(#) $Id: regexp.n,v 1.3 1999/04/16 00:46:35 stanton Exp $
'\" 
.so man.macros
.TH regexp n 8.1 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
regexp \- Match a regular expression against a string






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
'\"
'\" Copyright (c) 1998 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
'\" RCS: @(#) $Id: regexp.n,v 1.3.4.1 1999/04/28 20:59:08 welch Exp $
'\" 
.so man.macros
.TH regexp n 8.1 Tcl "Tcl Built-In Commands"
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
regexp \- Match a regular expression against a string
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
where \fIc\fR is alphanumeric
(possibly followed by other characters),
an \fIescape\fR (AREs only),
see ESCAPES below
.TP
\fB{\fR
when followed by a character other than a digit,
matches the character
`\fB{\fR';
when followed by a digit, it is the beginning of a
\fIbound\fR (see above)
.TP
\fIx\fR
where \fIx\fR is
a single character with no other significance, matches that character.
.RE







|
<







200
201
202
203
204
205
206
207

208
209
210
211
212
213
214
where \fIc\fR is alphanumeric
(possibly followed by other characters),
an \fIescape\fR (AREs only),
see ESCAPES below
.TP
\fB{\fR
when followed by a character other than a digit,
matches the left-brace character `\fB{\fR';

when followed by a digit, it is the beginning of a
\fIbound\fR (see above)
.TP
\fIx\fR
where \fIx\fR is
a single character with no other significance, matches that character.
.RE
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
\fInegative lookahead\fR (AREs only), matches at any point
where no substring matching \fIre\fR begins
.RE
.PP
The lookahead constraints may not contain back references (see later),
and all parentheses within them are considered non-capturing.
.PP
An RE may not end with
`\fB\e\fR'.

.SH "BRACKET EXPRESSIONS"
A \fIbracket expression\fR is a list of characters enclosed in
`\fB[\|]\fR'.
It normally matches any single character from the list (but see below).
If the list begins with
`\fB^\fR',
it matches any single character
(but see below) \fInot\fR from the rest of the list.
.PP
If two characters in the list are separated by
`\fB\-\fR',
this is shorthand
for the full \fIrange\fR of characters between those two (inclusive) in the
collating sequence,
e.g.
\fB[0\-9]\fR
in ASCII matches any decimal digit.
Two ranges may not share an







|
<


|
<

|
<



|
<







234
235
236
237
238
239
240
241

242
243
244

245
246

247
248
249
250

251
252
253
254
255
256
257
\fInegative lookahead\fR (AREs only), matches at any point
where no substring matching \fIre\fR begins
.RE
.PP
The lookahead constraints may not contain back references (see later),
and all parentheses within them are considered non-capturing.
.PP
An RE may not end with `\fB\e\fR'.


.SH "BRACKET EXPRESSIONS"
A \fIbracket expression\fR is a list of characters enclosed in `\fB[\|]\fR'.

It normally matches any single character from the list (but see below).
If the list begins with `\fB^\fR',

it matches any single character
(but see below) \fInot\fR from the rest of the list.
.PP
If two characters in the list are separated by `\fB\-\fR',

this is shorthand
for the full \fIrange\fR of characters between those two (inclusive) in the
collating sequence,
e.g.
\fB[0\-9]\fR
in ASCII matches any decimal digit.
Two ranges may not share an
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
enclose it in
\fB[.\fR
and
\fB.]\fR
to make it a collating element (see below).
Alternatively,
make it the first character
(following a possible
`\fB^\fR'),
or (AREs only) precede it with
`\fB\e\fR'.
Alternatively, for
`\fB\-\fR',
make it the last character,
or the second endpoint of a range.
To use a literal
\fB\-\fR
as the first endpoint of a range,
make it a collating element
or (AREs only) precede it with
`\fB\e\fR'.
With the exception of these, some combinations using
\fB[\fR
(see next
paragraphs), and escapes,
all other special characters lose their
special significance within a bracket expression.
.PP







|
<
|
<
|
<






|
<







270
271
272
273
274
275
276
277

278

279

280
281
282
283
284
285
286

287
288
289
290
291
292
293
enclose it in
\fB[.\fR
and
\fB.]\fR
to make it a collating element (see below).
Alternatively,
make it the first character
(following a possible `\fB^\fR'),

or (AREs only) precede it with `\fB\e\fR'.

Alternatively, for `\fB\-\fR',

make it the last character,
or the second endpoint of a range.
To use a literal
\fB\-\fR
as the first endpoint of a range,
make it a collating element
or (AREs only) precede it with `\fB\e\fR'.

With the exception of these, some combinations using
\fB[\fR
(see next
paragraphs), and escapes,
all other special characters lose their
special significance within a bracket expression.
.PP
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
elements appear in the bracket expression!
If the collating sequence includes a
\fBch\fR
multi-character collating element,
then the RE
\fB[[.ch.]]*c\fR
matches the first five characters
of
`\fBchchcc\fR',
and the RE
\fB[^c]b\fR
matches all of
`\fBchb\fR'.
.PP
Within a bracket expression, a collating element enclosed in
\fB[=\fR
and
\fB=]\fR
is an equivalence class, standing for the sequences of characters
of all collating elements equivalent to that one, including itself.
(If there are no other equivalent collating elements,
the treatment is as if the enclosing delimiters were
`\fB[.\fR'\&
and
`\fB.]\fR'.)
For example, if
\fBo\fR
and
\fB\o'o^'\fR
are the members of an equivalence class,
then 
`\fB[[=o=]]\fR',
`\fB[[=\o'o^'=]]\fR',
and
`\fB[o\o'o^']\fR'\&
are all synonymous.
An equivalence class may not be an endpoint
of a range.
.PP
Within a bracket expression, the name of a \fIcharacter class\fR enclosed
in
\fB[:\fR







<
|


|
<








|
<
<
|





<
<
|
<
|







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
elements appear in the bracket expression!
If the collating sequence includes a
\fBch\fR
multi-character collating element,
then the RE
\fB[[.ch.]]*c\fR
matches the first five characters

of `\fBchchcc\fR',
and the RE
\fB[^c]b\fR
matches all of `\fBchb\fR'.

.PP
Within a bracket expression, a collating element enclosed in
\fB[=\fR
and
\fB=]\fR
is an equivalence class, standing for the sequences of characters
of all collating elements equivalent to that one, including itself.
(If there are no other equivalent collating elements,
the treatment is as if the enclosing delimiters were `\fB[.\fR'\&


and `\fB.]\fR'.)
For example, if
\fBo\fR
and
\fB\o'o^'\fR
are the members of an equivalence class,


then `\fB[[=o=]]\fR', `\fB[[=\o'o^'=]]\fR',

and `\fB[o\o'o^']\fR'\&
are all synonymous.
An equivalence class may not be an endpoint
of a range.
.PP
Within a bracket expression, the name of a \fIcharacter class\fR enclosed
in
\fB[:\fR
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
(where X is any character) the character whose
low-order 5 bits are the same as those of
\fIX\fR,
and whose other bits are all zero
.TP
\fB\ee\fR
the character whose collating-sequence name
is
`\fBESC\fR',
or failing that, the character with octal value 033
.TP
\fB\ef\fR
formfeed, as in C
.TP
\fB\en\fR
newline, as in C







<
|







428
429
430
431
432
433
434

435
436
437
438
439
440
441
442
(where X is any character) the character whose
low-order 5 bits are the same as those of
\fIX\fR,
and whose other bits are all zero
.TP
\fB\ee\fR
the character whose collating-sequence name

is `\fBESC\fR',
or failing that, the character with octal value 033
.TP
\fB\ef\fR
formfeed, as in C
.TP
\fB\en\fR
newline, as in C
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
is exactly three octal digits,
and is not a
back reference (see below))
the character whose octal value is
\fB0\fIxyz\fR
.RE
.PP
Hexadecimal digits are
`\fB0\fR'-`\fB9\fR',
`\fBa\fR'-`\fBf\fR',
and
`\fBA\fR'-`\fBF\fR'.
Octal digits are
`\fB0\fR'-`\fB7\fR'.
.PP
The character-entry escapes are always taken as ordinary characters.
For example,
\fB\e135\fR
is
\fB]\fR
in ASCII,
but
\fB\e135\fR
does not terminate a bracket expression.
Beware, however, that some applications (e.g., C compilers) interpret 
such sequences themselves before the regular-expression package
gets to see them, which may require doubling (quadrupling, etc.) the
`\fB\e\fR'.
.PP
Class-shorthand escapes (AREs only) provide shorthands for certain commonly-used
character classes:
.RS 2
.TP 10
\fB\ed\fR
\fB[[:digit:]]\fR







|
<
<
<
|
|
<












|
<







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
is exactly three octal digits,
and is not a
back reference (see below))
the character whose octal value is
\fB0\fIxyz\fR
.RE
.PP
Hexadecimal digits are `\fB0\fR'-`\fB9\fR', `\fBa\fR'-`\fBf\fR',



and `\fBA\fR'-`\fBF\fR'.
Octal digits are `\fB0\fR'-`\fB7\fR'.

.PP
The character-entry escapes are always taken as ordinary characters.
For example,
\fB\e135\fR
is
\fB]\fR
in ASCII,
but
\fB\e135\fR
does not terminate a bracket expression.
Beware, however, that some applications (e.g., C compilers) interpret 
such sequences themselves before the regular-expression package
gets to see them, which may require doubling (quadrupling, etc.) the `\fB\e\fR'.

.PP
Class-shorthand escapes (AREs only) provide shorthands for certain commonly-used
character classes:
.RS 2
.TP 10
\fB\ed\fR
\fB[[:digit:]]\fR
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
\fB[^[:space:]]\fR
.TP
\fB\eW\fR
\fB[^[:alnum:]_]\fR
(note underscore)
.RE
.PP
Within bracket expressions,
`\fB\ed\fR',
`\fB\es\fR',
and
`\fB\ew\fR'\&
lose their outer brackets,
and
`\fB\eD\fR',
`\fB\eS\fR',
and
`\fB\eW\fR'\&
are illegal.
.PP
A constraint escape (AREs only) is a constraint,
matching the empty string if specific conditions are met,
written as an escape:
.RS 2
.TP 6
\fB\eA\fR
matches only at the beginning of the string
(see MATCHING, below, for how this differs from
`\fB^\fR')
.TP
\fB\em\fR
matches only at the beginning of a word
.TP
\fB\eM\fR
matches only at the end of a word
.TP
\fB\ey\fR
matches only at the beginning or end of a word
.TP
\fB\eY\fR
matches only at a point which is not the beginning or end of a word
.TP
\fB\eZ\fR
matches only at the end of the string
(see MATCHING, below, for how this differs from
`\fB$\fR')
.TP
\fB\e\fIm\fR
(where
\fIm\fR
is a nonzero digit) a \fIback reference\fR, see below
.TP
\fB\e\fImnn\fR







|
<
<
<
|

<
|
<
<
|









|
<















|
<







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
\fB[^[:space:]]\fR
.TP
\fB\eW\fR
\fB[^[:alnum:]_]\fR
(note underscore)
.RE
.PP
Within bracket expressions, `\fB\ed\fR', `\fB\es\fR',



and `\fB\ew\fR'\&
lose their outer brackets,

and `\fB\eD\fR', `\fB\eS\fR',


and `\fB\eW\fR'\&
are illegal.
.PP
A constraint escape (AREs only) is a constraint,
matching the empty string if specific conditions are met,
written as an escape:
.RS 2
.TP 6
\fB\eA\fR
matches only at the beginning of the string
(see MATCHING, below, for how this differs from `\fB^\fR')

.TP
\fB\em\fR
matches only at the beginning of a word
.TP
\fB\eM\fR
matches only at the end of a word
.TP
\fB\ey\fR
matches only at the beginning or end of a word
.TP
\fB\eY\fR
matches only at a point which is not the beginning or end of a word
.TP
\fB\eZ\fR
matches only at the end of the string
(see MATCHING, below, for how this differs from `\fB$\fR')

.TP
\fB\e\fIm\fR
(where
\fIm\fR
is a nonzero digit) a \fIback reference\fR, see below
.TP
\fB\e\fImnn\fR
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
subexpression specified by the number,
so that (e.g.)
\fB([bc])\e1\fR
matches
\fBbb\fR
or
\fBcc\fR
but not
`\fBbc\fR'.
The subexpression must entirely precede the back reference in the RE.
Subexpressions are numbered in the order of their leading parentheses.
Non-capturing parentheses do not define subexpressions.
.PP
There is an inherent historical ambiguity between octal character-entry 
escapes and back references, which is resolved by heuristics,
as hinted at above.







|
<







598
599
600
601
602
603
604
605

606
607
608
609
610
611
612
subexpression specified by the number,
so that (e.g.)
\fB([bc])\e1\fR
matches
\fBbb\fR
or
\fBcc\fR
but not `\fBbc\fR'.

The subexpression must entirely precede the back reference in the RE.
Subexpressions are numbered in the order of their leading parentheses.
Non-capturing parentheses do not define subexpressions.
.PP
There is an inherent historical ambiguity between octal character-entry 
escapes and back references, which is resolved by heuristics,
as hinted at above.
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
.SH "METASYNTAX"
In addition to the main syntax described above, there are some special
forms and miscellaneous syntactic facilities available.
.PP
Normally the flavor of RE being used is specified by
application-dependent means.
However, this can be overridden by a \fIdirector\fR.
If an RE of any flavor begins with
`\fB***:\fR',
the rest of the RE is an ARE.
If an RE of any flavor begins with
`\fB***=\fR',
the rest of the RE is taken to be a literal string,
with all characters considered ordinary characters.
.PP
An ARE may begin with \fIembedded options\fR:
a sequence
\fB(?\fIxyz\fB)\fR
(where







|
<

|
<







620
621
622
623
624
625
626
627

628
629

630
631
632
633
634
635
636
.SH "METASYNTAX"
In addition to the main syntax described above, there are some special
forms and miscellaneous syntactic facilities available.
.PP
Normally the flavor of RE being used is specified by
application-dependent means.
However, this can be overridden by a \fIdirector\fR.
If an RE of any flavor begins with `\fB***:\fR',

the rest of the RE is an ARE.
If an RE of any flavor begins with `\fB***=\fR',

the rest of the RE is taken to be a literal string,
with all characters considered ordinary characters.
.PP
An ARE may begin with \fIembedded options\fR:
a sequence
\fB(?\fIxyz\fB)\fR
(where
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
\fIctype\fR(3)).
Exactly how a multi-line expanded-syntax RE
can be entered interactively by a user,
if at all, is application-specific;
expanded syntax is primarily a scripting facility.
.PP
Finally, in an ARE,
outside bracket expressions, the sequence 
`\fB(?#\fIttt\fB)\fR'
(where
\fIttt\fR
is any text not containing a 
`\fB)\fR')
is a comment,
completely ignored.
Again, this is not allowed between the characters of
multi-character symbols like
`\fB(?:\fR'.
Such comments are more a historical artifact than a useful facility,
and their use is deprecated;
use the expanded syntax instead.
.PP
\fINone\fR of these metasyntax extensions is available if the application
(or an initial
\fB***=\fR







|
<


|
<



|
<







713
714
715
716
717
718
719
720

721
722
723

724
725
726
727

728
729
730
731
732
733
734
\fIctype\fR(3)).
Exactly how a multi-line expanded-syntax RE
can be entered interactively by a user,
if at all, is application-specific;
expanded syntax is primarily a scripting facility.
.PP
Finally, in an ARE,
outside bracket expressions, the sequence `\fB(?#\fIttt\fB)\fR'

(where
\fIttt\fR
is any text not containing a `\fB)\fR')

is a comment,
completely ignored.
Again, this is not allowed between the characters of
multi-character symbols like `\fB(?:\fR'.

Such comments are more a historical artifact than a useful facility,
and their use is deprecated;
use the expanded syntax instead.
.PP
\fINone\fR of these metasyntax extensions is available if the application
(or an initial
\fB***=\fR
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
can be used to force longest and shortest preference, respectively,
on a subexpression or a whole RE.
.PP
Match lengths are measured in characters, not collating elements.
An empty string is considered longer than no match at all.
For example,
\fBbb*\fR
matches the three middle characters of
`\fBabbbc\fR',
\fB(week|wee)(night|knights)\fR
matches all ten characters of
`\fBweeknights\fR',
when
\fB(.*).*\fR
is matched against
\fBabc\fR
the parenthesized subexpression
matches all three characters, and
when







|
<

|
<







785
786
787
788
789
790
791
792

793
794

795
796
797
798
799
800
801
can be used to force longest and shortest preference, respectively,
on a subexpression or a whole RE.
.PP
Match lengths are measured in characters, not collating elements.
An empty string is considered longer than no match at all.
For example,
\fBbb*\fR
matches the three middle characters of `\fBabbbc\fR',

\fB(week|wee)(night|knights)\fR
matches all ten characters of `\fBweeknights\fR',

when
\fB(.*).*\fR
is matched against
\fBabc\fR
the parenthesized subexpression
matches all three characters, and
when
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
the effect is much as if all case distinctions had vanished from the
alphabet.
When an alphabetic that exists in multiple cases appears as an
ordinary character outside a bracket expression, it is effectively
transformed into a bracket expression containing both cases,
so that
\fBx\fR
becomes
`\fB[xX]\fR'.
When it appears inside a bracket expression, all case counterparts
of it are added to the bracket expression, so that
\fB[x]\fR
becomes
\fB[xX]\fR
and
\fB[^x]\fR
becomes
`\fB[^xX]\fR'.
.PP
If newline-sensitive matching is specified,
\fB.\fR
and bracket expressions using
\fB^\fR
will never match the newline character
(so that matches will never cross newlines unless the RE







<
|







<
|







809
810
811
812
813
814
815

816
817
818
819
820
821
822
823

824
825
826
827
828
829
830
831
the effect is much as if all case distinctions had vanished from the
alphabet.
When an alphabetic that exists in multiple cases appears as an
ordinary character outside a bracket expression, it is effectively
transformed into a bracket expression containing both cases,
so that
\fBx\fR

becomes `\fB[xX]\fR'.
When it appears inside a bracket expression, all case counterparts
of it are added to the bracket expression, so that
\fB[x]\fR
becomes
\fB[xX]\fR
and
\fB[^x]\fR

becomes `\fB[^xX]\fR'.
.PP
If newline-sensitive matching is specified,
\fB.\fR
and bracket expressions using
\fB^\fR
will never match the newline character
(so that matches will never cross newlines unless the RE
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
.PP
If partial newline-sensitive matching is specified,
this affects
\fB.\fR
and bracket expressions
as with newline-sensitive matching, but not
\fB^\fR
and
`\fB$\fR'.
.PP
If inverse partial newline-sensitive matching is specified,
this affects
\fB^\fR
and
\fB$\fR
as with







<
|







845
846
847
848
849
850
851

852
853
854
855
856
857
858
859
.PP
If partial newline-sensitive matching is specified,
this affects
\fB.\fR
and bracket expressions
as with newline-sensitive matching, but not
\fB^\fR

and `\fB$\fR'.
.PP
If inverse partial newline-sensitive matching is specified,
this affects
\fB^\fR
and
\fB$\fR
as with
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
the
\fB***\fR
syntax of directors likewise is outside the POSIX
syntax for both BREs and EREs.
.PP
Many of the ARE extensions are borrowed from Perl, but some have
been changed to clean them up, and a few Perl extensions are not present.
Incompatibilities of note include
`\fB\eb\fR',
`\fB\eB\fR',
the lack of special treatment for a trailing newline,
the addition of complemented bracket expressions to the things
affected by newline-sensitive matching,
the restrictions on parentheses and back references in lookahead constraints,
and the longest/shortest-match (rather than first-match) matching semantics.
.PP
The matching rules for REs containing both normal and non-greedy quantifiers







|
<
<







878
879
880
881
882
883
884
885


886
887
888
889
890
891
892
the
\fB***\fR
syntax of directors likewise is outside the POSIX
syntax for both BREs and EREs.
.PP
Many of the ARE extensions are borrowed from Perl, but some have
been changed to clean them up, and a few Perl extensions are not present.
Incompatibilities of note include `\fB\eb\fR', `\fB\eB\fR',


the lack of special treatment for a trailing newline,
the addition of complemented bracket expressions to the things
affected by newline-sensitive matching,
the restrictions on parentheses and back references in lookahead constraints,
and the longest/shortest-match (rather than first-match) matching semantics.
.PP
The matching rules for REs containing both normal and non-greedy quantifiers
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
was always an ordinary character.
Such sequences should be rare,
and will often result in an error because following characters
will not look like a valid bound.
.PP
In AREs,
\fB\e\fR
remains a special character within
`\fB[\|]\fR',
so a literal
\fB\e\fR
within
\fB[\|]\fR
must be written
`\fB\e\e\fR'.
\fB\e\e\fR
also gives a literal
\fB\e\fR
within
\fB[\|]\fR
in RREs,
but only truly paranoid programmers routinely doubled the backslash.
.PP
AREs report the longest/shortest match for the RE,
rather than the first found in a specified search order.
This may affect some RREs which were written in the expectation that
the first match would be reported.
(The careful crafting of RREs to optimize the search order for fast
matching is obsolete (AREs examine all possible matches
in parallel, and their performance is largely insensitive to their
complexity) but cases where the search order was exploited to deliberately 
find a match which was \fInot\fR the longest/shortest will need rewriting.)
.RE

.SH "BASIC REGULAR EXPRESSIONS"
BREs differ from EREs in several respects.
`\fB|\fR',
`\fB+\fR',
and
\fB?\fR
are ordinary characters and there is no equivalent
for their functionality.
The delimiters for bounds are
\fB\e{\fR
and
`\fB\e}\fR',
with
\fB{\fR
and
\fB}\fR
by themselves ordinary characters.
The parentheses for nested subexpressions are
\fB\e(\fR
and
`\fB\e)\fR',
with
\fB(\fR
and
\fB)\fR
by themselves ordinary characters.
\fB^\fR
is an ordinary character except at the beginning of the
RE or the beginning of a parenthesized subexpression,
\fB$\fR
is an ordinary character except at the end of the
RE or the end of a parenthesized subexpression,
and
\fB*\fR
is an ordinary character if it appears at the beginning of the
RE or the beginning of a parenthesized subexpression
(after a possible leading
`\fB^\fR').
Finally,
single-digit back references are available,
and
\fB\e<\fR
and
\fB\e>\fR
are synonyms for







|
<




|
<




















|
<
<






<
|







<
|















|
<







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
was always an ordinary character.
Such sequences should be rare,
and will often result in an error because following characters
will not look like a valid bound.
.PP
In AREs,
\fB\e\fR
remains a special character within `\fB[\|]\fR',

so a literal
\fB\e\fR
within
\fB[\|]\fR
must be written `\fB\e\e\fR'.

\fB\e\e\fR
also gives a literal
\fB\e\fR
within
\fB[\|]\fR
in RREs,
but only truly paranoid programmers routinely doubled the backslash.
.PP
AREs report the longest/shortest match for the RE,
rather than the first found in a specified search order.
This may affect some RREs which were written in the expectation that
the first match would be reported.
(The careful crafting of RREs to optimize the search order for fast
matching is obsolete (AREs examine all possible matches
in parallel, and their performance is largely insensitive to their
complexity) but cases where the search order was exploited to deliberately 
find a match which was \fInot\fR the longest/shortest will need rewriting.)
.RE

.SH "BASIC REGULAR EXPRESSIONS"
BREs differ from EREs in several respects.  `\fB|\fR', `\fB+\fR',


and
\fB?\fR
are ordinary characters and there is no equivalent
for their functionality.
The delimiters for bounds are
\fB\e{\fR

and `\fB\e}\fR',
with
\fB{\fR
and
\fB}\fR
by themselves ordinary characters.
The parentheses for nested subexpressions are
\fB\e(\fR

and `\fB\e)\fR',
with
\fB(\fR
and
\fB)\fR
by themselves ordinary characters.
\fB^\fR
is an ordinary character except at the beginning of the
RE or the beginning of a parenthesized subexpression,
\fB$\fR
is an ordinary character except at the end of the
RE or the end of a parenthesized subexpression,
and
\fB*\fR
is an ordinary character if it appears at the beginning of the
RE or the beginning of a parenthesized subexpression
(after a possible leading `\fB^\fR').

Finally,
single-digit back references are available,
and
\fB\e<\fR
and
\fB\e>\fR
are synonyms for
Changes to generic/tclDecls.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
 * tclDecls.h --
 *
 *	Declarations of functions in the platform independent public Tcl API.
 *
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: tclDecls.h,v 1.9 1999/04/21 21:50:25 rjohnson Exp $
 */

#ifndef _TCLDECLS
#define _TCLDECLS

/*
 * WARNING: This file is automatically generated by the tools/genStubs.tcl










|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
 * tclDecls.h --
 *
 *	Declarations of functions in the platform independent public Tcl API.
 *
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: tclDecls.h,v 1.9.2.1 1999/04/27 18:45:41 stanton Exp $
 */

#ifndef _TCLDECLS
#define _TCLDECLS

/*
 * WARNING: This file is automatically generated by the tools/genStubs.tcl
1525
1526
1527
1528
1529
1530
1531



1532



1533
1534
1535
1536
1537
1538
1539
    int (*tcl_ParseVarName) _ANSI_ARGS_((Tcl_Interp * interp, char * string, int numBytes, Tcl_Parse * parsePtr, int append)); /* 364 */
    char * (*tcl_GetCwd) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_DString * cwdPtr)); /* 365 */
    int (*tcl_Chdir) _ANSI_ARGS_((CONST char * dirName)); /* 366 */
    int (*tcl_Access) _ANSI_ARGS_((CONST char * path, int mode)); /* 367 */
    int (*tcl_Stat) _ANSI_ARGS_((CONST char * path, struct stat * bufPtr)); /* 368 */
} TclStubs;




extern TclStubs *tclStubsPtr;




#if defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS)

/*
 * Inline function declarations:
 */








>
>
>

>
>
>







1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
    int (*tcl_ParseVarName) _ANSI_ARGS_((Tcl_Interp * interp, char * string, int numBytes, Tcl_Parse * parsePtr, int append)); /* 364 */
    char * (*tcl_GetCwd) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_DString * cwdPtr)); /* 365 */
    int (*tcl_Chdir) _ANSI_ARGS_((CONST char * dirName)); /* 366 */
    int (*tcl_Access) _ANSI_ARGS_((CONST char * path, int mode)); /* 367 */
    int (*tcl_Stat) _ANSI_ARGS_((CONST char * path, struct stat * bufPtr)); /* 368 */
} TclStubs;

#ifdef __cplusplus
extern "C" {
#endif
extern TclStubs *tclStubsPtr;
#ifdef __cplusplus
}
#endif

#if defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS)

/*
 * Inline function declarations:
 */

Changes to generic/tclIntDecls.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * tclIntDecls.h --
 *
 *	This file contains the declarations for all unsupported
 *	functions that are exported by the Tcl library.  These
 *	interfaces are not guaranteed to remain the same between
 *	versions.  Use at your own risk.
 *
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: tclIntDecls.h,v 1.7 1999/04/21 21:50:27 rjohnson Exp $
 */

#ifndef _TCLINTDECLS
#define _TCLINTDECLS

/*
 * WARNING: This file is automatically generated by the tools/genStubs.tcl













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * tclIntDecls.h --
 *
 *	This file contains the declarations for all unsupported
 *	functions that are exported by the Tcl library.  These
 *	interfaces are not guaranteed to remain the same between
 *	versions.  Use at your own risk.
 *
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: tclIntDecls.h,v 1.7.2.1 1999/04/27 18:45:42 stanton Exp $
 */

#ifndef _TCLINTDECLS
#define _TCLINTDECLS

/*
 * WARNING: This file is automatically generated by the tools/genStubs.tcl
589
590
591
592
593
594
595



596



597
598
599
600
601
602
603
    int (*tclpChdir) _ANSI_ARGS_((CONST char * dirName)); /* 137 */
    char * (*tclGetEnv) _ANSI_ARGS_((CONST char * name, Tcl_DString * valuePtr)); /* 138 */
    int (*tclpLoadFile) _ANSI_ARGS_((Tcl_Interp * interp, char * fileName, char * sym1, char * sym2, Tcl_PackageInitProc ** proc1Ptr, Tcl_PackageInitProc ** proc2Ptr, ClientData * clientDataPtr)); /* 139 */
    int (*tclLooksLikeInt) _ANSI_ARGS_((char * bytes, int length)); /* 140 */
    char * (*tclpGetCwd) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_DString * cwdPtr)); /* 141 */
} TclIntStubs;




extern TclIntStubs *tclIntStubsPtr;




#if defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS)

/*
 * Inline function declarations:
 */








>
>
>

>
>
>







589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
    int (*tclpChdir) _ANSI_ARGS_((CONST char * dirName)); /* 137 */
    char * (*tclGetEnv) _ANSI_ARGS_((CONST char * name, Tcl_DString * valuePtr)); /* 138 */
    int (*tclpLoadFile) _ANSI_ARGS_((Tcl_Interp * interp, char * fileName, char * sym1, char * sym2, Tcl_PackageInitProc ** proc1Ptr, Tcl_PackageInitProc ** proc2Ptr, ClientData * clientDataPtr)); /* 139 */
    int (*tclLooksLikeInt) _ANSI_ARGS_((char * bytes, int length)); /* 140 */
    char * (*tclpGetCwd) _ANSI_ARGS_((Tcl_Interp * interp, Tcl_DString * cwdPtr)); /* 141 */
} TclIntStubs;

#ifdef __cplusplus
extern "C" {
#endif
extern TclIntStubs *tclIntStubsPtr;
#ifdef __cplusplus
}
#endif

#if defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS)

/*
 * Inline function declarations:
 */

Changes to generic/tclIntPlatDecls.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * tclIntPlatDecls.h --
 *
 *	This file contains the declarations for all platform dependent
 *	unsupported functions that are exported by the Tcl library.  These
 *	interfaces are not guaranteed to remain the same between
 *	versions.  Use at your own risk.
 *
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 * All rights reserved.
 *
 * RCS: @(#) $Id: tclIntPlatDecls.h,v 1.5 1999/04/16 00:46:48 stanton Exp $
 */

#ifndef _TCLINTPLATDECLS
#define _TCLINTPLATDECLS

/*
 * WARNING: This file is automatically generated by the tools/genStubs.tcl











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * tclIntPlatDecls.h --
 *
 *	This file contains the declarations for all platform dependent
 *	unsupported functions that are exported by the Tcl library.  These
 *	interfaces are not guaranteed to remain the same between
 *	versions.  Use at your own risk.
 *
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 * All rights reserved.
 *
 * RCS: @(#) $Id: tclIntPlatDecls.h,v 1.5.4.1 1999/04/27 18:45:42 stanton Exp $
 */

#ifndef _TCLINTPLATDECLS
#define _TCLINTPLATDECLS

/*
 * WARNING: This file is automatically generated by the tools/genStubs.tcl
264
265
266
267
268
269
270



271



272
273
274
275
276
277
278
    int (*tclMacCreateEnv) _ANSI_ARGS_((void)); /* 22 */
    FILE * (*tclMacFOpenHack) _ANSI_ARGS_((CONST char * path, CONST char * mode)); /* 23 */
    void *reserved24;
    int (*tclMacChmod) _ANSI_ARGS_((char * path, int mode)); /* 25 */
#endif /* MAC_TCL */
} TclIntPlatStubs;




extern TclIntPlatStubs *tclIntPlatStubsPtr;




#if defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS)

/*
 * Inline function declarations:
 */








>
>
>

>
>
>







264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
    int (*tclMacCreateEnv) _ANSI_ARGS_((void)); /* 22 */
    FILE * (*tclMacFOpenHack) _ANSI_ARGS_((CONST char * path, CONST char * mode)); /* 23 */
    void *reserved24;
    int (*tclMacChmod) _ANSI_ARGS_((char * path, int mode)); /* 25 */
#endif /* MAC_TCL */
} TclIntPlatStubs;

#ifdef __cplusplus
extern "C" {
#endif
extern TclIntPlatStubs *tclIntPlatStubsPtr;
#ifdef __cplusplus
}
#endif

#if defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS)

/*
 * Inline function declarations:
 */

Changes to generic/tclParse.c.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 *
 * Copyright (c) 1997 Sun Microsystems, Inc.
 * Copyright (c) 1998 by Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: tclParse.c,v 1.5 1999/04/21 21:50:27 rjohnson Exp $
 */

#include "tclInt.h"
#include "tclPort.h"

/*
 * The following table provides parsing information about each possible







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 *
 * Copyright (c) 1997 Sun Microsystems, Inc.
 * Copyright (c) 1998 by Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: tclParse.c,v 1.5.2.1 1999/04/29 23:19:04 stanton Exp $
 */

#include "tclInt.h"
#include "tclPort.h"

/*
 * The following table provides parsing information about each possible
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496

    parsePtr->commandSize = src - parsePtr->commandStart;
    string[numBytes] = (char) savedChar;
    return TCL_OK;

    error:
    string[numBytes] = (char) savedChar;
    if (parsePtr->tokenPtr != parsePtr->staticTokens) {
	ckfree((char *) parsePtr->tokenPtr);
	parsePtr->tokenPtr = parsePtr->staticTokens;
    }
    if (parsePtr->commandStart == NULL) {
	parsePtr->commandStart = string;
    }
    parsePtr->commandSize = parsePtr->term - parsePtr->commandStart;
    return TCL_ERROR;
}








<
|
<
<







479
480
481
482
483
484
485

486


487
488
489
490
491
492
493

    parsePtr->commandSize = src - parsePtr->commandStart;
    string[numBytes] = (char) savedChar;
    return TCL_OK;

    error:
    string[numBytes] = (char) savedChar;

    Tcl_FreeParse(parsePtr);


    if (parsePtr->commandStart == NULL) {
	parsePtr->commandStart = string;
    }
    parsePtr->commandSize = parsePtr->term - parsePtr->commandStart;
    return TCL_ERROR;
}

1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
    tokenPtr = &parsePtr->tokenPtr[varIndex];
    tokenPtr->type = TCL_TOKEN_TEXT;
    tokenPtr->size = 1;
    tokenPtr->numComponents = 0;
    return TCL_OK;

    error:
    if (parsePtr->tokenPtr != parsePtr->staticTokens) {
	ckfree((char *) parsePtr->tokenPtr);
	parsePtr->tokenPtr = parsePtr->staticTokens;
    }
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ParseVar --







<
|
<
<







1736
1737
1738
1739
1740
1741
1742

1743


1744
1745
1746
1747
1748
1749
1750
    tokenPtr = &parsePtr->tokenPtr[varIndex];
    tokenPtr->type = TCL_TOKEN_TEXT;
    tokenPtr->size = 1;
    tokenPtr->numComponents = 0;
    return TCL_OK;

    error:

    Tcl_FreeParse(parsePtr);


    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ParseVar --
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
    }
    if (termPtr != NULL) {
	*termPtr = src+1;
    }
    return TCL_OK;

    error:
    if (parsePtr->tokenPtr != parsePtr->staticTokens) {
	ckfree((char *) parsePtr->tokenPtr);
	parsePtr->tokenPtr = parsePtr->staticTokens;
    }
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ParseQuotedString --







<
|
<
<







1975
1976
1977
1978
1979
1980
1981

1982


1983
1984
1985
1986
1987
1988
1989
    }
    if (termPtr != NULL) {
	*termPtr = src+1;
    }
    return TCL_OK;

    error:

    Tcl_FreeParse(parsePtr);


    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_ParseQuotedString --
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
    }
    if (termPtr != NULL) {
	*termPtr = (parsePtr->term + 1);
    }
    return TCL_OK;

    error:
    if (parsePtr->tokenPtr != parsePtr->staticTokens) {
	ckfree((char *) parsePtr->tokenPtr);
	parsePtr->tokenPtr = parsePtr->staticTokens;
    }
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * CommandComplete --







<
|
<
<







2066
2067
2068
2069
2070
2071
2072

2073


2074
2075
2076
2077
2078
2079
2080
    }
    if (termPtr != NULL) {
	*termPtr = (parsePtr->term + 1);
    }
    return TCL_OK;

    error:

    Tcl_FreeParse(parsePtr);


    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * CommandComplete --
2109
2110
2111
2112
2113
2114
2115

2116
2117
2118
2119
2120
2121
2122
2123
2124

2125
2126
2127


2128

2129
2130
2131
2132
2133
2134
2135
2136
static int
CommandComplete(script, length)
    char *script;			/* Script to check. */
    int length;				/* Number of bytes in script. */
{
    Tcl_Parse parse;
    char *p, *end;


    p = script;
    end = p + length;
    while (Tcl_ParseCommand((Tcl_Interp *) NULL, p, end - p, 0, &parse)
	    == TCL_OK) {
	p = parse.commandStart + parse.commandSize;
	if (*p == 0) {
	    break;
	}

    }
    if (parse.incomplete) {
	return 0;


    }

    return 1;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_CommandComplete --
 *







>









>


|
>
>

>
|







2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
static int
CommandComplete(script, length)
    char *script;			/* Script to check. */
    int length;				/* Number of bytes in script. */
{
    Tcl_Parse parse;
    char *p, *end;
    int result;

    p = script;
    end = p + length;
    while (Tcl_ParseCommand((Tcl_Interp *) NULL, p, end - p, 0, &parse)
	    == TCL_OK) {
	p = parse.commandStart + parse.commandSize;
	if (*p == 0) {
	    break;
	}
	Tcl_FreeParse(&parse);
    }
    if (parse.incomplete) {
	result = 0;
    } else {
	result = 1;
    }
    Tcl_FreeParse(&parse);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_CommandComplete --
 *
Changes to generic/tclPlatDecls.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
 * tclPlatDecls.h --
 *
 *	Declarations of platform specific Tcl APIs.
 *
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 * All rights reserved.
 *
 * RCS: @(#) $Id: tclPlatDecls.h,v 1.4 1999/04/16 00:46:51 stanton Exp $
 */

#ifndef _TCLPLATDECLS
#define _TCLPLATDECLS

/* !BEGIN!: Do not edit below this line. */









|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
 * tclPlatDecls.h --
 *
 *	Declarations of platform specific Tcl APIs.
 *
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 * All rights reserved.
 *
 * RCS: @(#) $Id: tclPlatDecls.h,v 1.4.4.1 1999/04/27 18:45:43 stanton Exp $
 */

#ifndef _TCLPLATDECLS
#define _TCLPLATDECLS

/* !BEGIN!: Do not edit below this line. */

76
77
78
79
80
81
82



83



84
85
86
87
88
89
90
    void (*tcl_SetOSTypeObj) _ANSI_ARGS_((Tcl_Obj * objPtr, OSType osType)); /* 5 */
    Tcl_Obj * (*tcl_NewOSTypeObj) _ANSI_ARGS_((OSType osType)); /* 6 */
    int (*strncasecmp) _ANSI_ARGS_((CONST char * s1, CONST char * s2, size_t n)); /* 7 */
    int (*strcasecmp) _ANSI_ARGS_((CONST char * s1, CONST char * s2)); /* 8 */
#endif /* MAC_TCL */
} TclPlatStubs;




extern TclPlatStubs *tclPlatStubsPtr;




#if defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS)

/*
 * Inline function declarations:
 */








>
>
>

>
>
>







76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
    void (*tcl_SetOSTypeObj) _ANSI_ARGS_((Tcl_Obj * objPtr, OSType osType)); /* 5 */
    Tcl_Obj * (*tcl_NewOSTypeObj) _ANSI_ARGS_((OSType osType)); /* 6 */
    int (*strncasecmp) _ANSI_ARGS_((CONST char * s1, CONST char * s2, size_t n)); /* 7 */
    int (*strcasecmp) _ANSI_ARGS_((CONST char * s1, CONST char * s2)); /* 8 */
#endif /* MAC_TCL */
} TclPlatStubs;

#ifdef __cplusplus
extern "C" {
#endif
extern TclPlatStubs *tclPlatStubsPtr;
#ifdef __cplusplus
}
#endif

#if defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS)

/*
 * Inline function declarations:
 */

Changes to generic/tclStubInit.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* 
 * tclStubInit.c --
 *
 *	This file contains the initializers for the Tcl stub vectors.
 *
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: tclStubInit.c,v 1.10 1999/04/21 21:50:28 rjohnson Exp $
 */

#include "tclInt.h"
#include "tclPort.h"

/*
 * Remove macros that will interfere with the definitions below.










|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* 
 * tclStubInit.c --
 *
 *	This file contains the initializers for the Tcl stub vectors.
 *
 * Copyright (c) 1998-1999 by Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: tclStubInit.c,v 1.10.2.1 1999/04/24 00:09:11 stanton Exp $
 */

#include "tclInt.h"
#include "tclPort.h"

/*
 * Remove macros that will interfere with the definitions below.
36
37
38
39
40
41
42















































































































































































































































43




44
45
46
47
48
49
50
 * WARNING: The contents of this file is automatically generated by the
 * tools/genStubs.tcl script. Any modifications to the function declarations
 * below should be made in the generic/tcl.decls script.
 */

/* !BEGIN!: Do not edit below this line. */
















































































































































































































































static TclStubHooks tclStubHooks;





TclStubs tclStubs = {
    TCL_STUB_MAGIC,
    &tclStubHooks,
    Tcl_PkgProvideEx, /* 0 */
    Tcl_PkgRequireEx, /* 1 */
    Tcl_Panic, /* 2 */







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>







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
 * WARNING: The contents of this file is automatically generated by the
 * tools/genStubs.tcl script. Any modifications to the function declarations
 * below should be made in the generic/tcl.decls script.
 */

/* !BEGIN!: Do not edit below this line. */

TclIntStubs tclIntStubs = {
    TCL_STUB_MAGIC,
    NULL,
    TclAccess, /* 0 */
    TclAccessDeleteProc, /* 1 */
    TclAccessInsertProc, /* 2 */
    TclAllocateFreeObjects, /* 3 */
    NULL, /* 4 */
    TclCleanupChildren, /* 5 */
    TclCleanupCommand, /* 6 */
    TclCopyAndCollapse, /* 7 */
    TclCopyChannel, /* 8 */
    TclCreatePipeline, /* 9 */
    TclCreateProc, /* 10 */
    TclDeleteCompiledLocalVars, /* 11 */
    TclDeleteVars, /* 12 */
    TclDoGlob, /* 13 */
    TclDumpMemoryInfo, /* 14 */
    NULL, /* 15 */
    TclExprFloatError, /* 16 */
    TclFileAttrsCmd, /* 17 */
    TclFileCopyCmd, /* 18 */
    TclFileDeleteCmd, /* 19 */
    TclFileMakeDirsCmd, /* 20 */
    TclFileRenameCmd, /* 21 */
    TclFindElement, /* 22 */
    TclFindProc, /* 23 */
    TclFormatInt, /* 24 */
    TclFreePackageInfo, /* 25 */
    NULL, /* 26 */
    TclGetDate, /* 27 */
    TclpGetDefaultStdChannel, /* 28 */
    TclGetElementOfIndexedArray, /* 29 */
    NULL, /* 30 */
    TclGetExtension, /* 31 */
    TclGetFrame, /* 32 */
    TclGetInterpProc, /* 33 */
    TclGetIntForIndex, /* 34 */
    TclGetIndexedScalar, /* 35 */
    TclGetLong, /* 36 */
    TclGetLoadedPackages, /* 37 */
    TclGetNamespaceForQualName, /* 38 */
    TclGetObjInterpProc, /* 39 */
    TclGetOpenMode, /* 40 */
    TclGetOriginalCommand, /* 41 */
    TclpGetUserHome, /* 42 */
    TclGlobalInvoke, /* 43 */
    TclGuessPackageName, /* 44 */
    TclHideUnsafeCommands, /* 45 */
    TclInExit, /* 46 */
    TclIncrElementOfIndexedArray, /* 47 */
    TclIncrIndexedScalar, /* 48 */
    TclIncrVar2, /* 49 */
    TclInitCompiledLocals, /* 50 */
    TclInterpInit, /* 51 */
    TclInvoke, /* 52 */
    TclInvokeObjectCommand, /* 53 */
    TclInvokeStringCommand, /* 54 */
    TclIsProc, /* 55 */
    NULL, /* 56 */
    NULL, /* 57 */
    TclLookupVar, /* 58 */
    TclpMatchFiles, /* 59 */
    TclNeedSpace, /* 60 */
    TclNewProcBodyObj, /* 61 */
    TclObjCommandComplete, /* 62 */
    TclObjInterpProc, /* 63 */
    TclObjInvoke, /* 64 */
    TclObjInvokeGlobal, /* 65 */
    TclOpenFileChannelDeleteProc, /* 66 */
    TclOpenFileChannelInsertProc, /* 67 */
    TclpAccess, /* 68 */
    TclpAlloc, /* 69 */
    TclpCopyFile, /* 70 */
    TclpCopyDirectory, /* 71 */
    TclpCreateDirectory, /* 72 */
    TclpDeleteFile, /* 73 */
    TclpFree, /* 74 */
    TclpGetClicks, /* 75 */
    TclpGetSeconds, /* 76 */
    TclpGetTime, /* 77 */
    TclpGetTimeZone, /* 78 */
    TclpListVolumes, /* 79 */
    TclpOpenFileChannel, /* 80 */
    TclpRealloc, /* 81 */
    TclpRemoveDirectory, /* 82 */
    TclpRenameFile, /* 83 */
    NULL, /* 84 */
    NULL, /* 85 */
    NULL, /* 86 */
    NULL, /* 87 */
    TclPrecTraceProc, /* 88 */
    TclPreventAliasLoop, /* 89 */
    NULL, /* 90 */
    TclProcCleanupProc, /* 91 */
    TclProcCompileProc, /* 92 */
    TclProcDeleteProc, /* 93 */
    TclProcInterpProc, /* 94 */
    TclpStat, /* 95 */
    TclRenameCommand, /* 96 */
    TclResetShadowedCmdRefs, /* 97 */
    TclServiceIdle, /* 98 */
    TclSetElementOfIndexedArray, /* 99 */
    TclSetIndexedScalar, /* 100 */
    TclSetPreInitScript, /* 101 */
    TclSetupEnv, /* 102 */
    TclSockGetPort, /* 103 */
    TclSockMinimumBuffers, /* 104 */
    TclStat, /* 105 */
    TclStatDeleteProc, /* 106 */
    TclStatInsertProc, /* 107 */
    TclTeardownNamespace, /* 108 */
    TclUpdateReturnInfo, /* 109 */
    NULL, /* 110 */
    Tcl_AddInterpResolvers, /* 111 */
    Tcl_AppendExportList, /* 112 */
    Tcl_CreateNamespace, /* 113 */
    Tcl_DeleteNamespace, /* 114 */
    Tcl_Export, /* 115 */
    Tcl_FindCommand, /* 116 */
    Tcl_FindNamespace, /* 117 */
    Tcl_GetInterpResolvers, /* 118 */
    Tcl_GetNamespaceResolvers, /* 119 */
    Tcl_FindNamespaceVar, /* 120 */
    Tcl_ForgetImport, /* 121 */
    Tcl_GetCommandFromObj, /* 122 */
    Tcl_GetCommandFullName, /* 123 */
    Tcl_GetCurrentNamespace, /* 124 */
    Tcl_GetGlobalNamespace, /* 125 */
    Tcl_GetVariableFullName, /* 126 */
    Tcl_Import, /* 127 */
    Tcl_PopCallFrame, /* 128 */
    Tcl_PushCallFrame, /* 129 */
    Tcl_RemoveInterpResolvers, /* 130 */
    Tcl_SetNamespaceResolvers, /* 131 */
    TclpHasSockets, /* 132 */
    TclpGetDate, /* 133 */
    TclpStrftime, /* 134 */
    TclpCheckStackSpace, /* 135 */
    NULL, /* 136 */
    TclpChdir, /* 137 */
    TclGetEnv, /* 138 */
    TclpLoadFile, /* 139 */
    TclLooksLikeInt, /* 140 */
    TclpGetCwd, /* 141 */
};

TclIntPlatStubs tclIntPlatStubs = {
    TCL_STUB_MAGIC,
    NULL,
#if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */
    TclGetAndDetachPids, /* 0 */
    TclpCloseFile, /* 1 */
    TclpCreateCommandChannel, /* 2 */
    TclpCreatePipe, /* 3 */
    TclpCreateProcess, /* 4 */
    NULL, /* 5 */
    TclpMakeFile, /* 6 */
    TclpOpenFile, /* 7 */
    TclUnixWaitForFile, /* 8 */
    TclpCreateTempFile, /* 9 */
#endif /* UNIX */
#ifdef __WIN32__
    TclWinConvertError, /* 0 */
    TclWinConvertWSAError, /* 1 */
    TclWinGetServByName, /* 2 */
    TclWinGetSockOpt, /* 3 */
    TclWinGetTclInstance, /* 4 */
    NULL, /* 5 */
    TclWinNToHS, /* 6 */
    TclWinSetSockOpt, /* 7 */
    TclpGetPid, /* 8 */
    TclWinGetPlatformId, /* 9 */
    TclWinSynchSpawn, /* 10 */
    TclGetAndDetachPids, /* 11 */
    TclpCloseFile, /* 12 */
    TclpCreateCommandChannel, /* 13 */
    TclpCreatePipe, /* 14 */
    TclpCreateProcess, /* 15 */
    NULL, /* 16 */
    NULL, /* 17 */
    TclpMakeFile, /* 18 */
    TclpOpenFile, /* 19 */
    TclWinAddProcess, /* 20 */
    TclpAsyncMark, /* 21 */
    TclpCreateTempFile, /* 22 */
    TclpGetTZName, /* 23 */
    TclWinNoBackslash, /* 24 */
#endif /* __WIN32__ */
#ifdef MAC_TCL
    TclpSysAlloc, /* 0 */
    TclpSysFree, /* 1 */
    TclpSysRealloc, /* 2 */
    TclpExit, /* 3 */
    FSpGetDefaultDir, /* 4 */
    FSpSetDefaultDir, /* 5 */
    FSpFindFolder, /* 6 */
    GetGlobalMouse, /* 7 */
    FSpGetDirectoryID, /* 8 */
    FSpOpenResFileCompat, /* 9 */
    FSpCreateResFileCompat, /* 10 */
    FSpLocationFromPath, /* 11 */
    FSpPathFromLocation, /* 12 */
    TclMacExitHandler, /* 13 */
    TclMacInitExitToShell, /* 14 */
    TclMacInstallExitToShellPatch, /* 15 */
    TclMacOSErrorToPosixError, /* 16 */
    TclMacRemoveTimer, /* 17 */
    TclMacStartTimer, /* 18 */
    TclMacTimerExpired, /* 19 */
    TclMacRegisterResourceFork, /* 20 */
    TclMacUnRegisterResourceFork, /* 21 */
    TclMacCreateEnv, /* 22 */
    TclMacFOpenHack, /* 23 */
    NULL, /* 24 */
    TclMacChmod, /* 25 */
#endif /* MAC_TCL */
};

TclPlatStubs tclPlatStubs = {
    TCL_STUB_MAGIC,
    NULL,
#ifdef __WIN32__
    Tcl_WinUtfToTChar, /* 0 */
    Tcl_WinTCharToUtf, /* 1 */
#endif /* __WIN32__ */
#ifdef MAC_TCL
    Tcl_MacSetEventProc, /* 0 */
    Tcl_MacConvertTextResource, /* 1 */
    Tcl_MacEvalResource, /* 2 */
    Tcl_MacFindResource, /* 3 */
    Tcl_GetOSTypeFromObj, /* 4 */
    Tcl_SetOSTypeObj, /* 5 */
    Tcl_NewOSTypeObj, /* 6 */
    strncasecmp, /* 7 */
    strcasecmp, /* 8 */
#endif /* MAC_TCL */
};

static TclStubHooks tclStubHooks = {
    &tclPlatStubs,
    &tclIntStubs,
    &tclIntPlatStubs
};

TclStubs tclStubs = {
    TCL_STUB_MAGIC,
    &tclStubHooks,
    Tcl_PkgProvideEx, /* 0 */
    Tcl_PkgRequireEx, /* 1 */
    Tcl_Panic, /* 2 */
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
    Tcl_ParseQuotedString, /* 363 */
    Tcl_ParseVarName, /* 364 */
    Tcl_GetCwd, /* 365 */
    Tcl_Chdir, /* 366 */
    Tcl_Access, /* 367 */
    Tcl_Stat, /* 368 */
};

TclIntStubs tclIntStubs = {
    TCL_STUB_MAGIC,
    NULL,
    TclAccess, /* 0 */
    TclAccessDeleteProc, /* 1 */
    TclAccessInsertProc, /* 2 */
    TclAllocateFreeObjects, /* 3 */
    NULL, /* 4 */
    TclCleanupChildren, /* 5 */
    TclCleanupCommand, /* 6 */
    TclCopyAndCollapse, /* 7 */
    TclCopyChannel, /* 8 */
    TclCreatePipeline, /* 9 */
    TclCreateProc, /* 10 */
    TclDeleteCompiledLocalVars, /* 11 */
    TclDeleteVars, /* 12 */
    TclDoGlob, /* 13 */
    TclDumpMemoryInfo, /* 14 */
    NULL, /* 15 */
    TclExprFloatError, /* 16 */
    TclFileAttrsCmd, /* 17 */
    TclFileCopyCmd, /* 18 */
    TclFileDeleteCmd, /* 19 */
    TclFileMakeDirsCmd, /* 20 */
    TclFileRenameCmd, /* 21 */
    TclFindElement, /* 22 */
    TclFindProc, /* 23 */
    TclFormatInt, /* 24 */
    TclFreePackageInfo, /* 25 */
    NULL, /* 26 */
    TclGetDate, /* 27 */
    TclpGetDefaultStdChannel, /* 28 */
    TclGetElementOfIndexedArray, /* 29 */
    NULL, /* 30 */
    TclGetExtension, /* 31 */
    TclGetFrame, /* 32 */
    TclGetInterpProc, /* 33 */
    TclGetIntForIndex, /* 34 */
    TclGetIndexedScalar, /* 35 */
    TclGetLong, /* 36 */
    TclGetLoadedPackages, /* 37 */
    TclGetNamespaceForQualName, /* 38 */
    TclGetObjInterpProc, /* 39 */
    TclGetOpenMode, /* 40 */
    TclGetOriginalCommand, /* 41 */
    TclpGetUserHome, /* 42 */
    TclGlobalInvoke, /* 43 */
    TclGuessPackageName, /* 44 */
    TclHideUnsafeCommands, /* 45 */
    TclInExit, /* 46 */
    TclIncrElementOfIndexedArray, /* 47 */
    TclIncrIndexedScalar, /* 48 */
    TclIncrVar2, /* 49 */
    TclInitCompiledLocals, /* 50 */
    TclInterpInit, /* 51 */
    TclInvoke, /* 52 */
    TclInvokeObjectCommand, /* 53 */
    TclInvokeStringCommand, /* 54 */
    TclIsProc, /* 55 */
    NULL, /* 56 */
    NULL, /* 57 */
    TclLookupVar, /* 58 */
    TclpMatchFiles, /* 59 */
    TclNeedSpace, /* 60 */
    TclNewProcBodyObj, /* 61 */
    TclObjCommandComplete, /* 62 */
    TclObjInterpProc, /* 63 */
    TclObjInvoke, /* 64 */
    TclObjInvokeGlobal, /* 65 */
    TclOpenFileChannelDeleteProc, /* 66 */
    TclOpenFileChannelInsertProc, /* 67 */
    TclpAccess, /* 68 */
    TclpAlloc, /* 69 */
    TclpCopyFile, /* 70 */
    TclpCopyDirectory, /* 71 */
    TclpCreateDirectory, /* 72 */
    TclpDeleteFile, /* 73 */
    TclpFree, /* 74 */
    TclpGetClicks, /* 75 */
    TclpGetSeconds, /* 76 */
    TclpGetTime, /* 77 */
    TclpGetTimeZone, /* 78 */
    TclpListVolumes, /* 79 */
    TclpOpenFileChannel, /* 80 */
    TclpRealloc, /* 81 */
    TclpRemoveDirectory, /* 82 */
    TclpRenameFile, /* 83 */
    NULL, /* 84 */
    NULL, /* 85 */
    NULL, /* 86 */
    NULL, /* 87 */
    TclPrecTraceProc, /* 88 */
    TclPreventAliasLoop, /* 89 */
    NULL, /* 90 */
    TclProcCleanupProc, /* 91 */
    TclProcCompileProc, /* 92 */
    TclProcDeleteProc, /* 93 */
    TclProcInterpProc, /* 94 */
    TclpStat, /* 95 */
    TclRenameCommand, /* 96 */
    TclResetShadowedCmdRefs, /* 97 */
    TclServiceIdle, /* 98 */
    TclSetElementOfIndexedArray, /* 99 */
    TclSetIndexedScalar, /* 100 */
    TclSetPreInitScript, /* 101 */
    TclSetupEnv, /* 102 */
    TclSockGetPort, /* 103 */
    TclSockMinimumBuffers, /* 104 */
    TclStat, /* 105 */
    TclStatDeleteProc, /* 106 */
    TclStatInsertProc, /* 107 */
    TclTeardownNamespace, /* 108 */
    TclUpdateReturnInfo, /* 109 */
    NULL, /* 110 */
    Tcl_AddInterpResolvers, /* 111 */
    Tcl_AppendExportList, /* 112 */
    Tcl_CreateNamespace, /* 113 */
    Tcl_DeleteNamespace, /* 114 */
    Tcl_Export, /* 115 */
    Tcl_FindCommand, /* 116 */
    Tcl_FindNamespace, /* 117 */
    Tcl_GetInterpResolvers, /* 118 */
    Tcl_GetNamespaceResolvers, /* 119 */
    Tcl_FindNamespaceVar, /* 120 */
    Tcl_ForgetImport, /* 121 */
    Tcl_GetCommandFromObj, /* 122 */
    Tcl_GetCommandFullName, /* 123 */
    Tcl_GetCurrentNamespace, /* 124 */
    Tcl_GetGlobalNamespace, /* 125 */
    Tcl_GetVariableFullName, /* 126 */
    Tcl_Import, /* 127 */
    Tcl_PopCallFrame, /* 128 */
    Tcl_PushCallFrame, /* 129 */
    Tcl_RemoveInterpResolvers, /* 130 */
    Tcl_SetNamespaceResolvers, /* 131 */
    TclpHasSockets, /* 132 */
    TclpGetDate, /* 133 */
    TclpStrftime, /* 134 */
    TclpCheckStackSpace, /* 135 */
    NULL, /* 136 */
    TclpChdir, /* 137 */
    TclGetEnv, /* 138 */
    TclpLoadFile, /* 139 */
    TclLooksLikeInt, /* 140 */
    TclpGetCwd, /* 141 */
};

TclIntPlatStubs tclIntPlatStubs = {
    TCL_STUB_MAGIC,
    NULL,
#if !defined(__WIN32__) && !defined(MAC_TCL) /* UNIX */
    TclGetAndDetachPids, /* 0 */
    TclpCloseFile, /* 1 */
    TclpCreateCommandChannel, /* 2 */
    TclpCreatePipe, /* 3 */
    TclpCreateProcess, /* 4 */
    NULL, /* 5 */
    TclpMakeFile, /* 6 */
    TclpOpenFile, /* 7 */
    TclUnixWaitForFile, /* 8 */
    TclpCreateTempFile, /* 9 */
#endif /* UNIX */
#ifdef __WIN32__
    TclWinConvertError, /* 0 */
    TclWinConvertWSAError, /* 1 */
    TclWinGetServByName, /* 2 */
    TclWinGetSockOpt, /* 3 */
    TclWinGetTclInstance, /* 4 */
    NULL, /* 5 */
    TclWinNToHS, /* 6 */
    TclWinSetSockOpt, /* 7 */
    TclpGetPid, /* 8 */
    TclWinGetPlatformId, /* 9 */
    TclWinSynchSpawn, /* 10 */
    TclGetAndDetachPids, /* 11 */
    TclpCloseFile, /* 12 */
    TclpCreateCommandChannel, /* 13 */
    TclpCreatePipe, /* 14 */
    TclpCreateProcess, /* 15 */
    NULL, /* 16 */
    NULL, /* 17 */
    TclpMakeFile, /* 18 */
    TclpOpenFile, /* 19 */
    TclWinAddProcess, /* 20 */
    TclpAsyncMark, /* 21 */
    TclpCreateTempFile, /* 22 */
    TclpGetTZName, /* 23 */
    TclWinNoBackslash, /* 24 */
#endif /* __WIN32__ */
#ifdef MAC_TCL
    TclpSysAlloc, /* 0 */
    TclpSysFree, /* 1 */
    TclpSysRealloc, /* 2 */
    TclpExit, /* 3 */
    FSpGetDefaultDir, /* 4 */
    FSpSetDefaultDir, /* 5 */
    FSpFindFolder, /* 6 */
    GetGlobalMouse, /* 7 */
    FSpGetDirectoryID, /* 8 */
    FSpOpenResFileCompat, /* 9 */
    FSpCreateResFileCompat, /* 10 */
    FSpLocationFromPath, /* 11 */
    FSpPathFromLocation, /* 12 */
    TclMacExitHandler, /* 13 */
    TclMacInitExitToShell, /* 14 */
    TclMacInstallExitToShellPatch, /* 15 */
    TclMacOSErrorToPosixError, /* 16 */
    TclMacRemoveTimer, /* 17 */
    TclMacStartTimer, /* 18 */
    TclMacTimerExpired, /* 19 */
    TclMacRegisterResourceFork, /* 20 */
    TclMacUnRegisterResourceFork, /* 21 */
    TclMacCreateEnv, /* 22 */
    TclMacFOpenHack, /* 23 */
    NULL, /* 24 */
    TclMacChmod, /* 25 */
#endif /* MAC_TCL */
};

TclPlatStubs tclPlatStubs = {
    TCL_STUB_MAGIC,
    NULL,
#ifdef __WIN32__
    Tcl_WinUtfToTChar, /* 0 */
    Tcl_WinTCharToUtf, /* 1 */
#endif /* __WIN32__ */
#ifdef MAC_TCL
    Tcl_MacSetEventProc, /* 0 */
    Tcl_MacConvertTextResource, /* 1 */
    Tcl_MacEvalResource, /* 2 */
    Tcl_MacFindResource, /* 3 */
    Tcl_GetOSTypeFromObj, /* 4 */
    Tcl_SetOSTypeObj, /* 5 */
    Tcl_NewOSTypeObj, /* 6 */
    strncasecmp, /* 7 */
    strcasecmp, /* 8 */
#endif /* MAC_TCL */
};

static TclStubHooks tclStubHooks = {
    &tclPlatStubs,
    &tclIntStubs,
    &tclIntPlatStubs
};


/* !END!: Do not edit above this line. */








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

678
679
680
681
682
683
684
685






















































































































































































































































686
    Tcl_ParseQuotedString, /* 363 */
    Tcl_ParseVarName, /* 364 */
    Tcl_GetCwd, /* 365 */
    Tcl_Chdir, /* 366 */
    Tcl_Access, /* 367 */
    Tcl_Stat, /* 368 */
};























































































































































































































































/* !END!: Do not edit above this line. */
Added library/encoding/koi8-r.enc.








































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Encoding file: koi8-r, single-byte
S
003F 0 1
00
0000000100020003000400050006000700080009000A000B000C000D000E000F
0010001100120013001400150016001700180019001A001B001C001D001E001F
0020002100220023002400250026002700280029002A002B002C002D002E002F
0030003100320033003400350036003700380039003A003B003C003D003E003F
0040004100420043004400450046004700480049004A004B004C004D004E004F
0050005100520053005400550056005700580059005A005B005C005D005E005F
0060006100620063006400650066006700680069006A006B006C006D006E006F
0070007100720073007400750076007700780079007A007B007C007D007E007F
25002502250C251025142518251C2524252C2534253C258025842588258C2590
259125922593232025A02219221A22482264226500A0232100B000B200B700F7
25502551255204512553255425552556255725582559255A255B255C255D255E
255F25602561040125622563256425652566256725682569256A256B256C00A9
044E0430043104460434043504440433044504380439043A043B043C043D043E
043F044F044004410442044304360432044C044B04370448044D04490447044A
042E0410041104260414041504240413042504180419041A041B041C041D041E
041F042F042004210422042304160412042C042B04170428042D04290427042A
Changes to mac/README.
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
Tcl 8.1b2 for Macintosh

by Ray Johnson
Scriptics Corporation
[email protected]
with major help from
Jim Ingham
Cygnus Solutions
[email protected]

RCS: @(#) $Id: README,v 1.6 1999/04/16 00:47:19 stanton Exp $

1. Introduction
---------------

This is the README file for the Macintosh version of the Tcl
scripting language.  The file consists of information specific
to the Macintosh version of Tcl.  For more general information
please read the README file in the main Tcl directory.

2. What's new?
--------------

Internationalization!  This is the first Tcl release that features
can handle international characters.

On the Macintosh, the System Encoding is taken from the script of the
Finder Font as set in the Views control panel, or in the Finder
Preferences in OS8.0.

See the main Tcl README for other features new to Tcl 8.

3. Mac specific features
------------------------

There are several features or enhancements in Tcl that are unique to 
the Macintosh version of Tcl.  Here is a list of those features and
pointers to where you can find more information about the feature.

* The "resource" command allows you manipulate Macintosh resources.
  A complete man page is available for this command.

* The Mac version of the "source" command has an option to source from
  a Macintosh resource.  Check the man page from the source command
  for details.

* The only command NOT available on the Mac is the exec command.
  However, we include a Mac only package called Tclapplescript that
  provides access to Mac's AppleScript system.  This command is still
  under design & construction.  Documentatin can be found in the "HTML
  Docs:tcl8.1" folder in a file called "AppleScript.html".

* The env variable on the Macintosh works rather differently than on
  Windows or UNIX platforms.  Check out the tclvars man page for
  details.

* The command "file volumes" returns the available volumes on your
  Macintosh.  Check out the file command for details.

* The command "file attributes" has the Mac specific options of
  -creator and -type which allow you to query and set the Macintosh
  creator and type codes for Mac files.  See file man page for details.

* We have added a template for creating a Background-only Tcl application.
  So you can use Tcl as a faceless server process.  For more details, see 
  the file background.doc.
  
If you are writing cross platform code but would still like to use
some of these Mac specific commands, please remember to use the
tcl_platform variable to special case your code.


4. The Distribution
-------------------

Macintosh Tcl is distributed in three different forms.  This 
should make it easier to only download what you need.  The 
packages are as follows:

mactk8.1b2.sea.hqx

    This distribution is a "binary" only release.  It contains an
    installer program that will install a 68k, PowerPC, or Fat
    version of the "Tcl Shell" and "Wish" applications.  In addition,
    it installs the Tcl & Tk libraries in the Extensions folder inside
    your System Folder.

mactcltk-full-8.1b2.sea.hqx

    This release contains the full release of Tcl and Tk for the
    Macintosh plus the More Files packages which Macintosh Tcl and Tk
    rely on.

mactcl-source-8.1b2.sea.hqx

    This release contains the complete source for Tcl 8.1.  In
    addition, Metrowerks CodeWarrior libraries and project files
    are included.  However, you must already have the More Files
    package to compile this code.

5. Documentation
----------------

The "html" subdirectory contains reference documentation in
in the HTML format.  You may also find these pages at:

	http://www.scriptics.com/man/tcl8.1/contents.html

Other documentation and sample Tcl scripts can be found at
the Tcl archive site: 

	ftp://ftp.neosoft.com/tcl/

and the Tcl resource center:

	http://www.scriptics.com/resource/

The internet news group comp.lang.tcl is also a valuable
source of information about Tcl.  A mailing list is also
available (see below).

6. Compiling Tcl
----------------

In order to compile Macintosh Tcl you must have the 
following items:

	CodeWarrior Pro 2 or 3
	Mac Tcl 8.1 (source)
	More Files 1.4.3

There are two sets of project files included with the package. The ones
we use for the release are for CodeWarrior Pro 3, and are not compatible
with CodeWarrior Gold release 11 and earlier. We have included the files
for earlier versions of CodeWarrior in the folder tcl8.1:mac:CW11 Projects,
but they are unsupported, and a little out of date.

As of Tcl8.0p2, the code will also build under CW Pro 2.  The only
change that needs to be made is that float.mac.c should be replaced by
float.c in the MacTcl MSL project file.

However, there seems to be a bug in the CFM68K Linker in CW Pro 2,
which renders the CFM68K Version under CW Pro 2 very unstable.  I am
working with MetroWerks to resolve this issue.  The PPC version is
fine, as is the Traditional 68K Shell.  But if you need to use the
CFM68K, then you must stay with CW Pro 1 for now.

The project  files included with the Mac Tcl source should work 
fine.  The only thing you may need to update are the access paths.
Unfortunantly, it's somewhat common for the project files to become
slightly corrupted.  The most common problem is that the "Prefix file"
found in the "C/C++ Preference" panel is incorrect.  This should be
set to MW_TclHeaderPPC, MW_TclHeader68K or MW_TclHeaderCFM68K.

To build the fat version of TclShell, open the project file "TclShells.�",
select the "TclShell" target, and build. All of the associated binaries will
be built automoatically. There are also targets for building static 68K
and Power PC builds, for building a CFM 68K build, and for building a
shared library Power PC only build.

Special notes:

* There is a small bug in More Files 1.4.3.  Also you should not use
  MoreFiles 1.4.4 - 1.4.6.  Look in the file named morefiles.doc for
  more details.

* You may not have the libmoto library which will cause a compile 
  error.  You don't REALLY need it - it can be removed.  Look at the
  file libmoto.doc for more details.

* Check out the file bugs.doc for information about known bugs.

If you have comments or Bug reports send them to:
Jim Ingham
[email protected]

|









|





|
<
<
|
<
<

<
<
|
<
<
<
|
<

|
<
|
<
<
<

<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|






|







|





|






<
<
<





<
<
<
<
<
<
<
<
<
<
<
<
<
|









<
<
<
<
<
|
<
<
<
|
<
<
<
<
<

<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





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
Tcl 8.1 for Macintosh

by Ray Johnson
Scriptics Corporation
[email protected]
with major help from
Jim Ingham
Cygnus Solutions
[email protected]

RCS: @(#) $Id: README,v 1.6.4.1 1999/04/22 23:04:36 welch Exp $

1. Introduction
---------------

This is the README file for the Macintosh version of the Tcl
scripting language.  The home page for the Macintosh releases is


	http://www.scriptics.com/mac/





A summary of what's new in this release is at



	http://www.scriptics.com/software/whatsnew81.html


A summary of Macintosh-specific features is at

	http://www.scriptics.com/mac/features.html





































2. The Distribution
-------------------

Macintosh Tcl is distributed in three different forms.  This 
should make it easier to only download what you need.  The 
packages are as follows:

mactk8.1.sea.hqx

    This distribution is a "binary" only release.  It contains an
    installer program that will install a 68k, PowerPC, or Fat
    version of the "Tcl Shell" and "Wish" applications.  In addition,
    it installs the Tcl & Tk libraries in the Extensions folder inside
    your System Folder.

mactcltk-full-8.1.sea.hqx

    This release contains the full release of Tcl and Tk for the
    Macintosh plus the More Files packages which Macintosh Tcl and Tk
    rely on.

mactcl-source-8.1.sea.hqx

    This release contains the complete source for Tcl 8.1.  In
    addition, Metrowerks CodeWarrior libraries and project files
    are included.  However, you must already have the More Files
    package to compile this code.




The "html" subdirectory contains reference documentation in
in the HTML format.  You may also find these pages at:

	http://www.scriptics.com/man/tcl8.1/contents.html














3. Compiling Tcl
----------------

In order to compile Macintosh Tcl you must have the 
following items:

	CodeWarrior Pro 2 or 3
	Mac Tcl 8.1 (source)
	More Files 1.4.3






The included project files should work fine.  However, for



current release notes please check this page:












	http://www.scriptics.com/support/howto/compile.html#mac


















If you have comments or Bug reports send them to:
Jim Ingham
[email protected]

Changes to tests/env.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Commands covered:  none (tests environment variable implementation)
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright (c) 1991-1993 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: env.test,v 1.4 1999/04/16 00:47:26 stanton Exp $

if {[lsearch [namespace children] ::tcltest] == -1} {
    source [file join [pwd] [file dirname [info script]] defs.tcl]
}

#
# These tests will run on any platform (and indeed crashed













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Commands covered:  none (tests environment variable implementation)
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright (c) 1991-1993 The Regents of the University of California.
# Copyright (c) 1994 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: env.test,v 1.4.4.1 1999/04/26 21:14:56 rjohnson Exp $

if {[lsearch [namespace children] ::tcltest] == -1} {
    source [file join [pwd] [file dirname [info script]] defs.tcl]
}

#
# These tests will run on any platform (and indeed crashed
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
    set result [getenv]
    unset env(\ub6)
    set result
} "\ub6=\ua7"

test env-5.0 {corner cases - set a value, it should exist} {} {
    set temp [lindex [array names env] end]
    set x env($temp)
    set env($temp) a
    set result [set env($temp)]
    set env($temp) $x
    set result
} {a}
test env-5.1 {corner cases - remove one elem at a time} {} {
    # When no environment variables exist, the env var will







|







169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
    set result [getenv]
    unset env(\ub6)
    set result
} "\ub6=\ua7"

test env-5.0 {corner cases - set a value, it should exist} {} {
    set temp [lindex [array names env] end]
    set x $env($temp)
    set env($temp) a
    set result [set env($temp)]
    set env($temp) $x
    set result
} {a}
test env-5.1 {corner cases - remove one elem at a time} {} {
    # When no environment variables exist, the env var will
Changes to tests/http.test.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
#
# RCS: @(#) $Id: http.test,v 1.4 1999/04/16 00:47:28 stanton Exp $

if {[lsearch [namespace children] ::tcltest] == -1} {
    source [file join [pwd] [file dirname [info script]] defs.tcl]
}

if {[catch {package require http 2.0}]} {
    if {[info exist http2]} {







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
#
# RCS: @(#) $Id: http.test,v 1.4.4.1 1999/04/22 23:04:37 welch Exp $

if {[lsearch [namespace children] ::tcltest] == -1} {
    source [file join [pwd] [file dirname [info script]] defs.tcl]
}

if {[catch {package require http 2.0}]} {
    if {[info exist http2]} {
32
33
34
35
36
37
38








39

40
41
42
43
44
45
46
    }
}


set port 8010
set bindata "This is binary data\x0d\x0amore\x0dmore\x0amore\x00null"









set httpdFile [file join $::tcltest::testsDir httpd]

if {[info commands testthread] == "testthread" && [file exists $httpdFile]} {
    set httpthread [testthread create "
	source $httpdFile
	testthread wait
    "]
    testthread send $httpthread [list set port $port]
    testthread send $httpthread [list set bindata $bindata]







>
>
>
>
>
>
>
>
|
>







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


set port 8010
set bindata "This is binary data\x0d\x0amore\x0dmore\x0amore\x00null"

# Ensure httpd file exists

set origFile [file join $::tcltest::testsDir httpd]
set newFile [file join $::tcltest::workingDir httpd]
if {![file exists $newFile]} {
    file copy $origFile $newFile
    set removeHttpd 1
}
set httpdFile [file join $::tcltest::workingDir httpd]

if {[info commands testthread] == "testthread" && [file exists $httpdFile]} {
    set httpthread [testthread create "
	source $httpdFile
	testthread wait
    "]
    testthread send $httpthread [list set port $port]
    testthread send $httpthread [list set bindata $bindata]
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
if {[info exists httpthread]} {
    testthread send -async $httpthread {
	testthread exit
    }
} else {
    close $listen
}
::tcltest::cleanupTests
return



















<
<

|
|
|

|
|
<
<
<
<
<
304
305
306
307
308
309
310


311
312
313
314
315
316
317





if {[info exists httpthread]} {
    testthread send -async $httpthread {
	testthread exit
    }
} else {
    close $listen
}



if {[info exist removeHttpd]} {
    remove $httpdFile
}

::tcltest::cleanupTests
return





Changes to tests/parse.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# This file contains a collection of tests for the procedures in the
# file tclParse.c.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright (c) 1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: parse.test,v 1.3 1999/04/16 00:47:31 stanton Exp $

if {[lsearch [namespace children] ::tcltest] == -1} {
    source [file join [pwd] [file dirname [info script]] defs.tcl]
}

if {[info commands testparser] == {}} {
    puts "This application hasn't been compiled with the \"testparser\""










|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# This file contains a collection of tests for the procedures in the
# file tclParse.c.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright (c) 1997 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: parse.test,v 1.3.4.1 1999/04/29 23:19:06 stanton Exp $

if {[lsearch [namespace children] ::tcltest] == -1} {
    source [file join [pwd] [file dirname [info script]] defs.tcl]
}

if {[info commands testparser] == {}} {
    puts "This application hasn't been compiled with the \"testparser\""
719
720
721
722
723
724
725




726
727
728
729
730
731
732
} 1
test parse-15.56 {CommandComplete procedure} {
    info complete "set x [bytestring \0]; \{"
} 0
test parse-15.57 {CommandComplete procedure} {
    info complete "# Comment should be complete command"
} 1





# cleanup
catch {unset a}
::tcltest::cleanupTests
return









>
>
>
>







719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
} 1
test parse-15.56 {CommandComplete procedure} {
    info complete "set x [bytestring \0]; \{"
} 0
test parse-15.57 {CommandComplete procedure} {
    info complete "# Comment should be complete command"
} 1
test parse-15.58 {CommandComplete procedure, memory leaks} {
    info complete "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22"
} 1


# cleanup
catch {unset a}
::tcltest::cleanupTests
return


Changes to tests/unixInit.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# The file tests the functions in the tclUnixInit.c file.
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright (c) 1997 by Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: unixInit.test,v 1.4 1999/04/21 21:50:31 rjohnson Exp $

if {[lsearch [namespace children] ::tcltest] == -1} {
    source [file join [pwd] [file dirname [info script]] defs.tcl]
}

catch {set oldlibrary $env(TCL_LIBRARY); unset env(TCL_LIBRARY)}
catch {set oldlang $env(LANG)}












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# The file tests the functions in the tclUnixInit.c file.
#
# This file contains a collection of tests for one or more of the Tcl
# built-in commands.  Sourcing this file into Tcl runs the tests and
# generates output for errors.  No output means no errors were found.
#
# Copyright (c) 1997 by Sun Microsystems, Inc.
# Copyright (c) 1998-1999 by Scriptics Corporation.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# RCS: @(#) $Id: unixInit.test,v 1.4.2.1 1999/04/24 01:08:23 rjohnson Exp $

if {[lsearch [namespace children] ::tcltest] == -1} {
    source [file join [pwd] [file dirname [info script]] defs.tcl]
}

catch {set oldlibrary $env(TCL_LIBRARY); unset env(TCL_LIBRARY)}
catch {set oldlang $env(LANG)}
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
    } else {
        set developLib tcl[info tclversion]/library
    }
    set prefix [file dirname [file dirname $tcltest]]

    set x {}
    lappend x [string compare [lindex $path 0] $prefix/$installLib]
    lappend x [string compare [lindex $path 1] [file dirname $prefix]/$developLib]
    set x
} {0 0}
test unixInit-2.2 {TclpInitLibraryPath: TCL_LIBRARY} {unixOnly installedTcl} {
    # ((str != NULL) && (str[0] != '\0')) 

    set env(TCL_LIBRARY) sparkly
    set path [getlibpath]







|







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
    } else {
        set developLib tcl[info tclversion]/library
    }
    set prefix [file dirname [file dirname $tcltest]]

    set x {}
    lappend x [string compare [lindex $path 0] $prefix/$installLib]
    lappend x [string compare [lindex $path 4] [file dirname $prefix]/$developLib]
    set x
} {0 0}
test unixInit-2.2 {TclpInitLibraryPath: TCL_LIBRARY} {unixOnly installedTcl} {
    # ((str != NULL) && (str[0] != '\0')) 

    set env(TCL_LIBRARY) sparkly
    set path [getlibpath]
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149

    file mkdir /tmp/sparkly/lib/tcl[info tclversion]
    close [open /tmp/sparkly/lib/tcl[info tclversion]/init.tcl w]

    set x [lrange [getlibpath /tmp/sparkly/bin/tcltest] 0 1]
    file delete -force /tmp/sparkly
    set x
} [list /tmp/sparkly/lib/tcl[info tclversion] /tmp/tcl[info tclversion]/library]
test unixInit-2.7 {TclpInitLibraryPath: compiled-in library path} \
	{emptyTest unixOnly} {
    # would need test command to get defaultLibDir and compare it to
    # [lindex $auto_path end]
} {}
test unixInit-3.1 {TclpSetInitialEncodings} {unixOnly installedTcl} {
    set env(LANG) C







|







135
136
137
138
139
140
141
142
143
144
145
146
147
148
149

    file mkdir /tmp/sparkly/lib/tcl[info tclversion]
    close [open /tmp/sparkly/lib/tcl[info tclversion]/init.tcl w]

    set x [lrange [getlibpath /tmp/sparkly/bin/tcltest] 0 1]
    file delete -force /tmp/sparkly
    set x
} [list /tmp/sparkly/lib/tcl[info tclversion] /tmp/lib/tcl[info tclversion]]
test unixInit-2.7 {TclpInitLibraryPath: compiled-in library path} \
	{emptyTest unixOnly} {
    # would need test command to get defaultLibDir and compare it to
    # [lindex $auto_path end]
} {}
test unixInit-3.1 {TclpSetInitialEncodings} {unixOnly installedTcl} {
    set env(LANG) C
Changes to tools/README.
1
2
3
4



















 This directory contains unsupported tools that are used
 during the release engineering process.























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

 This directory contains unsupported tools that are used
 during the release engineering process.

Generating HTML files.
The tcl8.1-tk8.1-man-html.tcl script from Robert Critchlow
generates a nice set of HTML with good cross references.
Use it like
    tclsh8.0 tcl8.1-tk8.1-man-html.tcl --htmldir=/tmp/tcl8.1
This script is very picky about the organization of man pages,
effectively acting as a style enforcer.

Generating Windows Help Files:
1) Build tcl in the ../unix directory
2) On UNIX, (after autoconf and configure), do
	make
    this converts the Nroff to RTF files.
2) On Windows, convert the RTF to a Help doc, do
	nmake helpfile

Generating Windows binary distribution.
Update and compile the WYSE tcl.wse configuration.
Changes to tools/configure.in.
1
2
3
4
5
6
7
8
9
10
11
12
dnl	This file is an input file used by the GNU "autoconf" program to
dnl	generate the file "configure", which is run to configure the
dnl	Makefile in this directory.
AC_INIT(man2tcl.c)
# RCS: @(#) $Id: configure.in,v 1.5 1999/04/16 00:47:38 stanton Exp $

# Recover information that Tcl computed with its configure script.

#--------------------------------------------------------------------
#       See if there was a command-line option for where Tcl is;  if
#       not, assume that its top-level directory is a sibling of ours.
#--------------------------------------------------------------------




|







1
2
3
4
5
6
7
8
9
10
11
12
dnl	This file is an input file used by the GNU "autoconf" program to
dnl	generate the file "configure", which is run to configure the
dnl	Makefile in this directory.
AC_INIT(man2tcl.c)
# RCS: @(#) $Id: configure.in,v 1.5.4.1 1999/04/29 23:20:36 stanton Exp $

# Recover information that Tcl computed with its configure script.

#--------------------------------------------------------------------
#       See if there was a command-line option for where Tcl is;  if
#       not, assume that its top-level directory is a sibling of ours.
#--------------------------------------------------------------------
26
27
28
29
30
31
32
33
34
CC=$TCL_CC
AC_SUBST(CC)
AC_SUBST(TCL_VERSION)
AC_SUBST(TCL_PATCH_LEVEL)
AC_SUBST(TCL_SRC_DIR)
AC_SUBST(TCL_BIN_DIR)

AC_OUTPUT(Makefile)
AC_OUTPUT(tcl.hpj)







|
<
26
27
28
29
30
31
32
33

CC=$TCL_CC
AC_SUBST(CC)
AC_SUBST(TCL_VERSION)
AC_SUBST(TCL_PATCH_LEVEL)
AC_SUBST(TCL_SRC_DIR)
AC_SUBST(TCL_BIN_DIR)

AC_OUTPUT(Makefile tcl.hpj)

Changes to tools/encoding/README.
1
2
3
4
5
Use "make" to compile all the encoding files (*.txt,*.esc) into the format
that Tcl can use (*.enc).  It is the caller's responsibility to move the
generated .enc files to the appropriate place (the $TCL_LIBRARY/encoding
directory).

|
|
|
|

1
2
3
4
5
On Unix, use "make" to compile all the encoding files (*.txt,*.esc)
into the format that Tcl can use (*.enc).  It is the caller's
responsibility to move the generated .enc files to the appropriate
place (the $TCL_LIBRARY/encoding directory).

Added tools/encoding/koi8-r.txt.
























































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
# KOI8-R
#  source: RFC1489 via Gabor Kiss <[email protected]>
#  and Andrey A. Chernov <[email protected]>
#
# Format:  Three tab-separated columns
#   Column #1 is the KOI8-R code (in hex as 0xXX)
#   Column #2 is the Unicode (in hex as 0xXXXX)
#   Column #3 the Unicode name (follows a comment sign, '#')
#
# The entries are in KOI8-R order
#

0x00 0x0000 # NULL
0x01 0x0001 # START OF HEADING
0x02 0x0002 # START OF TEXT
0x03 0x0003 # END OF TEXT
0x04 0x0004 # END OF TRANSMISSION
0x05 0x0005 # ENQUIRY
0x06 0x0006 # ACKNOWLEDGE
0x07 0x0007 # BELL
0x08 0x0008 # BACKSPACE
0x09 0x0009 # HORIZONTAL TABULATION
0x0A 0x000A # LINE FEED
0x0B 0x000B # VERTICAL TABULATION
0x0C 0x000C # FORM FEED
0x0D 0x000D # CARRIAGE RETURN
0x0E 0x000E # SHIFT OUT
0x0F 0x000F # SHIFT IN
0x10 0x0010 # DATA LINK ESCAPE
0x11 0x0011 # DEVICE CONTROL ONE
0x12 0x0012 # DEVICE CONTROL TWO
0x13 0x0013 # DEVICE CONTROL THREE
0x14 0x0014 # DEVICE CONTROL FOUR
0x15 0x0015 # NEGATIVE ACKNOWLEDGE
0x16 0x0016 # SYNCHRONOUS IDLE
0x17 0x0017 # END OF TRANSMISSION BLOCK
0x18 0x0018 # CANCEL
0x19 0x0019 # END OF MEDIUM
0x1A 0x001A # SUBSTITUTE
0x1B 0x001B # ESCAPE
0x1C 0x001C # FILE SEPARATOR
0x1D 0x001D # GROUP SEPARATOR
0x1E 0x001E # RECORD SEPARATOR
0x1F 0x001F # UNIT SEPARATOR
0x20 0x0020 # SPACE
0x21 0x0021 # EXCLAMATION MARK
0x22 0x0022 # QUOTATION MARK
0x23 0x0023 # NUMBER SIGN
0x24 0x0024 # DOLLAR SIGN
0x25 0x0025 # PERCENT SIGN
0x26 0x0026 # AMPERSAND
0x27 0x0027 # APOSTROPHE
0x28 0x0028 # LEFT PARENTHESIS
0x29 0x0029 # RIGHT PARENTHESIS
0x2A 0x002A # ASTERISK
0x2B 0x002B # PLUS SIGN
0x2C 0x002C # COMMA
0x2D 0x002D # HYPHEN-MINUS
0x2E 0x002E # FULL STOP
0x2F 0x002F # SOLIDUS
0x30 0x0030 # DIGIT ZERO
0x31 0x0031 # DIGIT ONE
0x32 0x0032 # DIGIT TWO
0x33 0x0033 # DIGIT THREE
0x34 0x0034 # DIGIT FOUR
0x35 0x0035 # DIGIT FIVE
0x36 0x0036 # DIGIT SIX
0x37 0x0037 # DIGIT SEVEN
0x38 0x0038 # DIGIT EIGHT
0x39 0x0039 # DIGIT NINE
0x3A 0x003A # COLON
0x3B 0x003B # SEMICOLON
0x3C 0x003C # LESS-THAN SIGN
0x3D 0x003D # EQUALS SIGN
0x3E 0x003E # GREATER-THAN SIGN
0x3F 0x003F # QUESTION MARK
0x40 0x0040 # COMMERCIAL AT
0x41 0x0041 # LATIN CAPITAL LETTER A
0x42 0x0042 # LATIN CAPITAL LETTER B
0x43 0x0043 # LATIN CAPITAL LETTER C
0x44 0x0044 # LATIN CAPITAL LETTER D
0x45 0x0045 # LATIN CAPITAL LETTER E
0x46 0x0046 # LATIN CAPITAL LETTER F
0x47 0x0047 # LATIN CAPITAL LETTER G
0x48 0x0048 # LATIN CAPITAL LETTER H
0x49 0x0049 # LATIN CAPITAL LETTER I
0x4A 0x004A # LATIN CAPITAL LETTER J
0x4B 0x004B # LATIN CAPITAL LETTER K
0x4C 0x004C # LATIN CAPITAL LETTER L
0x4D 0x004D # LATIN CAPITAL LETTER M
0x4E 0x004E # LATIN CAPITAL LETTER N
0x4F 0x004F # LATIN CAPITAL LETTER O
0x50 0x0050 # LATIN CAPITAL LETTER P
0x51 0x0051 # LATIN CAPITAL LETTER Q
0x52 0x0052 # LATIN CAPITAL LETTER R
0x53 0x0053 # LATIN CAPITAL LETTER S
0x54 0x0054 # LATIN CAPITAL LETTER T
0x55 0x0055 # LATIN CAPITAL LETTER U
0x56 0x0056 # LATIN CAPITAL LETTER V
0x57 0x0057 # LATIN CAPITAL LETTER W
0x58 0x0058 # LATIN CAPITAL LETTER X
0x59 0x0059 # LATIN CAPITAL LETTER Y
0x5A 0x005A # LATIN CAPITAL LETTER Z
0x5B 0x005B # LEFT SQUARE BRACKET
0x5C 0x005C # REVERSE SOLIDUS
0x5D 0x005D # RIGHT SQUARE BRACKET
0x5E 0x005E # CIRCUMFLEX ACCENT
0x5F 0x005F # LOW LINE
0x60 0x0060 # GRAVE ACCENT
0x61 0x0061 # LATIN SMALL LETTER A
0x62 0x0062 # LATIN SMALL LETTER B
0x63 0x0063 # LATIN SMALL LETTER C
0x64 0x0064 # LATIN SMALL LETTER D
0x65 0x0065 # LATIN SMALL LETTER E
0x66 0x0066 # LATIN SMALL LETTER F
0x67 0x0067 # LATIN SMALL LETTER G
0x68 0x0068 # LATIN SMALL LETTER H
0x69 0x0069 # LATIN SMALL LETTER I
0x6A 0x006A # LATIN SMALL LETTER J
0x6B 0x006B # LATIN SMALL LETTER K
0x6C 0x006C # LATIN SMALL LETTER L
0x6D 0x006D # LATIN SMALL LETTER M
0x6E 0x006E # LATIN SMALL LETTER N
0x6F 0x006F # LATIN SMALL LETTER O
0x70 0x0070 # LATIN SMALL LETTER P
0x71 0x0071 # LATIN SMALL LETTER Q
0x72 0x0072 # LATIN SMALL LETTER R
0x73 0x0073 # LATIN SMALL LETTER S
0x74 0x0074 # LATIN SMALL LETTER T
0x75 0x0075 # LATIN SMALL LETTER U
0x76 0x0076 # LATIN SMALL LETTER V
0x77 0x0077 # LATIN SMALL LETTER W
0x78 0x0078 # LATIN SMALL LETTER X
0x79 0x0079 # LATIN SMALL LETTER Y
0x7A 0x007A # LATIN SMALL LETTER Z
0x7B 0x007B # LEFT CURLY BRACKET
0x7C 0x007C # VERTICAL LINE
0x7D 0x007D # RIGHT CURLY BRACKET
0x7E 0x007E # TILDE
0x7F 0x007F # DELETE
0x80 0x2500 # BOX DRAWINGS LIGHT HORIZONTAL
0x81 0x2502 # BOX DRAWINGS LIGHT VERTICAL
0x82 0x250C # BOX DRAWINGS LIGHT DOWN AND RIGHT
0x83 0x2510 # BOX DRAWINGS LIGHT DOWN AND LEFT
0x84 0x2514 # BOX DRAWINGS LIGHT UP AND RIGHT
0x85 0x2518 # BOX DRAWINGS LIGHT UP AND LEFT
0x86 0x251C # BOX DRAWINGS LIGHT VERTICAL AND RIGHT
0x87 0x2524 # BOX DRAWINGS LIGHT VERTICAL AND LEFT
0x88 0x252C # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
0x89 0x2534 # BOX DRAWINGS LIGHT UP AND HORIZONTAL
0x8A 0x253C # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
0x8B 0x2580 # UPPER HALF BLOCK
0x8C 0x2584 # LOWER HALF BLOCK
0x8D 0x2588 # FULL BLOCK
0x8E 0x258C # LEFT HALF BLOCK
0x8F 0x2590 # RIGHT HALF BLOCK
0x90 0x2591 # LIGHT SHADE
0x91 0x2592 # MEDIUM SHADE
0x92 0x2593 # DARK SHADE
0x93 0x2320 # TOP HALF INTEGRAL
0x94 0x25A0 # BLACK SQUARE
0x95 0x2219 # BULLET OPERATOR
0x96 0x221A # SQUARE ROOT
0x97 0x2248 # ALMOST EQUAL TO
0x98 0x2264 # LESS-THAN OR EQUAL TO
0x99 0x2265 # GREATER-THAN OR EQUAL TO
0x9A 0x00A0 # NO-BREAK SPACE
0x9B 0x2321 # BOTTOM HALF INTEGRAL
0x9C 0x00B0 # DEGREE SIGN
0x9D 0x00B2 # SUPERSCRIPT TWO
0x9E 0x00B7 # MIDDLE DOT
0x9F 0x00F7 # DIVISION SIGN
0xA0 0x2550 # BOX DRAWINGS DOUBLE HORIZONTAL
0xA1 0x2551 # BOX DRAWINGS DOUBLE VERTICAL
0xA2 0x2552 # BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
0xA3 0x0451 # CYRILLIC SMALL LETTER IO
0xA4 0x2553 # BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
0xA5 0x2554 # BOX DRAWINGS DOUBLE DOWN AND RIGHT
0xA6 0x2555 # BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
0xA7 0x2556 # BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
0xA8 0x2557 # BOX DRAWINGS DOUBLE DOWN AND LEFT
0xA9 0x2558 # BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
0xAA 0x2559 # BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
0xAB 0x255A # BOX DRAWINGS DOUBLE UP AND RIGHT
0xAC 0x255B # BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
0xAD 0x255C # BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
0xAE 0x255D # BOX DRAWINGS DOUBLE UP AND LEFT
0xAF 0x255E # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
0xB0 0x255F # BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
0xB1 0x2560 # BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
0xB2 0x2561 # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
0xB3 0x0401 # CYRILLIC CAPITAL LETTER IO
0xB4 0x2562 # BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
0xB5 0x2563 # BOX DRAWINGS DOUBLE VERTICAL AND LEFT
0xB6 0x2564 # BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
0xB7 0x2565 # BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
0xB8 0x2566 # BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
0xB9 0x2567 # BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
0xBA 0x2568 # BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
0xBB 0x2569 # BOX DRAWINGS DOUBLE UP AND HORIZONTAL
0xBC 0x256A # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
0xBD 0x256B # BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
0xBE 0x256C # BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
0xBF 0x00A9 # COPYRIGHT SIGN
0xC0 0x044E # CYRILLIC SMALL LETTER YU
0xC1 0x0430 # CYRILLIC SMALL LETTER A
0xC2 0x0431 # CYRILLIC SMALL LETTER BE
0xC3 0x0446 # CYRILLIC SMALL LETTER TSE
0xC4 0x0434 # CYRILLIC SMALL LETTER DE
0xC5 0x0435 # CYRILLIC SMALL LETTER IE
0xC6 0x0444 # CYRILLIC SMALL LETTER EF
0xC7 0x0433 # CYRILLIC SMALL LETTER GHE
0xC8 0x0445 # CYRILLIC SMALL LETTER HA
0xC9 0x0438 # CYRILLIC SMALL LETTER I
0xCA 0x0439 # CYRILLIC SMALL LETTER SHORT I
0xCB 0x043A # CYRILLIC SMALL LETTER KA
0xCC 0x043B # CYRILLIC SMALL LETTER EL
0xCD 0x043C # CYRILLIC SMALL LETTER EM
0xCE 0x043D # CYRILLIC SMALL LETTER EN
0xCF 0x043E # CYRILLIC SMALL LETTER O
0xD0 0x043F # CYRILLIC SMALL LETTER PE
0xD1 0x044F # CYRILLIC SMALL LETTER YA
0xD2 0x0440 # CYRILLIC SMALL LETTER ER
0xD3 0x0441 # CYRILLIC SMALL LETTER ES
0xD4 0x0442 # CYRILLIC SMALL LETTER TE
0xD5 0x0443 # CYRILLIC SMALL LETTER U
0xD6 0x0436 # CYRILLIC SMALL LETTER ZHE
0xD7 0x0432 # CYRILLIC SMALL LETTER VE
0xD8 0x044C # CYRILLIC SMALL LETTER SOFT SIGN
0xD9 0x044B # CYRILLIC SMALL LETTER YERU
0xDA 0x0437 # CYRILLIC SMALL LETTER ZE
0xDB 0x0448 # CYRILLIC SMALL LETTER SHA
0xDC 0x044D # CYRILLIC SMALL LETTER E
0xDD 0x0449 # CYRILLIC SMALL LETTER SHCHA
0xDE 0x0447 # CYRILLIC SMALL LETTER CHE
0xDF 0x044A # CYRILLIC SMALL LETTER HARD SIGN
0xE0 0x042E # CYRILLIC CAPITAL LETTER YU
0xE1 0x0410 # CYRILLIC CAPITAL LETTER A
0xE2 0x0411 # CYRILLIC CAPITAL LETTER BE
0xE3 0x0426 # CYRILLIC CAPITAL LETTER TSE
0xE4 0x0414 # CYRILLIC CAPITAL LETTER DE
0xE5 0x0415 # CYRILLIC CAPITAL LETTER IE
0xE6 0x0424 # CYRILLIC CAPITAL LETTER EF
0xE7 0x0413 # CYRILLIC CAPITAL LETTER GHE
0xE8 0x0425 # CYRILLIC CAPITAL LETTER HA
0xE9 0x0418 # CYRILLIC CAPITAL LETTER I
0xEA 0x0419 # CYRILLIC CAPITAL LETTER SHORT I
0xEB 0x041A # CYRILLIC CAPITAL LETTER KA
0xEC 0x041B # CYRILLIC CAPITAL LETTER EL
0xED 0x041C # CYRILLIC CAPITAL LETTER EM
0xEE 0x041D # CYRILLIC CAPITAL LETTER EN
0xEF 0x041E # CYRILLIC CAPITAL LETTER O
0xF0 0x041F # CYRILLIC CAPITAL LETTER PE
0xF1 0x042F # CYRILLIC CAPITAL LETTER YA
0xF2 0x0420 # CYRILLIC CAPITAL LETTER ER
0xF3 0x0421 # CYRILLIC CAPITAL LETTER ES
0xF4 0x0422 # CYRILLIC CAPITAL LETTER TE
0xF5 0x0423 # CYRILLIC CAPITAL LETTER U
0xF6 0x0416 # CYRILLIC CAPITAL LETTER ZHE
0xF7 0x0412 # CYRILLIC CAPITAL LETTER VE
0xF8 0x042C # CYRILLIC CAPITAL LETTER SOFT SIGN
0xF9 0x042B # CYRILLIC CAPITAL LETTER YERU
0xFA 0x0417 # CYRILLIC CAPITAL LETTER ZE
0xFB 0x0428 # CYRILLIC CAPITAL LETTER SHA
0xFC 0x042D # CYRILLIC CAPITAL LETTER E
0xFD 0x0429 # CYRILLIC CAPITAL LETTER SHCHA
0xFE 0x0427 # CYRILLIC CAPITAL LETTER CHE
0xFF 0x042A # CYRILLIC CAPITAL LETTER HARD SIGN
Changes to tools/genStubs.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# genStubs.tcl --
#
#	This script generates a set of stub files for a given
#	interface.  
#	
#
# Copyright (c) 1998-1999 by Scriptics Corporation.
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
# 
# RCS: @(#) $Id: genStubs.tcl,v 1.3 1999/04/16 00:47:39 stanton Exp $

namespace eval genStubs {
    # libraryName --
    #
    #	The name of the entire library.  This value is used to compute
    #	the USE_*_STUB_PROCS macro and the name of the init file.











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# genStubs.tcl --
#
#	This script generates a set of stub files for a given
#	interface.  
#	
#
# Copyright (c) 1998-1999 by Scriptics Corporation.
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
# 
# RCS: @(#) $Id: genStubs.tcl,v 1.3.4.2 1999/04/27 18:45:43 stanton Exp $

namespace eval genStubs {
    # libraryName --
    #
    #	The name of the entire library.  This value is used to compute
    #	the USE_*_STUB_PROCS macro and the name of the init file.

713
714
715
716
717
718
719

720

721
722
723
724
725
726
727
    append text "    int magic;\n"
    append text "    struct ${capName}StubHooks *hooks;\n\n"

    emitSlots $name text

    append text "} ${capName}Stubs;\n"


    append text "\nextern ${capName}Stubs *${name}StubsPtr;\n"


    emitMacros $name text

    rewriteFile [file join $outDir ${name}Decls.h] $text
    return
}








>
|
>







713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
    append text "    int magic;\n"
    append text "    struct ${capName}StubHooks *hooks;\n\n"

    emitSlots $name text

    append text "} ${capName}Stubs;\n"

    append text "\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n"
    append text "extern ${capName}Stubs *${name}StubsPtr;\n"
    append text "#ifdef __cplusplus\n}\n#endif\n"

    emitMacros $name text

    rewriteFile [file join $outDir ${name}Decls.h] $text
    return
}

762
763
764
765
766
767
768
769






770
771
772
773
774
775
776
    variable hooks
    upvar $textVar text

    set capName [string toupper [string index $name 0]]
    append capName [string range $name 1 end]

    if {[info exists hooks($name)]} {
	append text "\nstatic ${capName}StubHooks ${name}StubHooks;\n"






    }
    append text "\n${capName}Stubs ${name}Stubs = \{\n"
    append text "    TCL_STUB_MAGIC,\n"
    if {[info exists hooks($name)]} {
	append text "    &${name}StubHooks,\n"
    } else {
	append text "    NULL,\n"







|
>
>
>
>
>
>







764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
    variable hooks
    upvar $textVar text

    set capName [string toupper [string index $name 0]]
    append capName [string range $name 1 end]

    if {[info exists hooks($name)]} {
 	append text "\nstatic ${capName}StubHooks ${name}StubHooks = \{\n"
	set sep "    "
	foreach sub $hooks($name) {
	    append text $sep "&${sub}Stubs"
	    set sep ",\n    "
	}
	append text "\n\};\n"
    }
    append text "\n${capName}Stubs ${name}Stubs = \{\n"
    append text "    TCL_STUB_MAGIC,\n"
    if {[info exists hooks($name)]} {
	append text "    &${name}StubHooks,\n"
    } else {
	append text "    NULL,\n"
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

proc genStubs::emitInits {} {
    variable hooks
    variable outDir
    variable libraryName
    variable interfaces






    foreach name [lsort [array names interfaces]] {

	emitInit $name text
    }



    foreach name [array names hooks] {
	set capName [string toupper [string index $name 0]]
	append capName [string range $name 1 end]

 	append text "\nstatic ${capName}StubHooks ${name}StubHooks = \{\n"
	set sep "    "
	foreach sub $hooks($name) {
	    append text $sep "&${sub}Stubs"
	    set sep ",\n    "
	}
	append text "\n\};\n\n"
    }

    rewriteFile [file join $outDir ${libraryName}StubInit.c] $text
}

# genStubs::init --
#







>
>
>
>
>

>
|
|
>
|
|
|
<
|
|
<
<
|
<
<
<
|







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

proc genStubs::emitInits {} {
    variable hooks
    variable outDir
    variable libraryName
    variable interfaces

    # Assuming that dependencies only go one level deep, we need to emit
    # all of the leaves first to avoid needing forward declarations.

    set leaves {}
    set roots {}
    foreach name [lsort [array names interfaces]] {
	if {[info exists hooks($name)]} {
	    lappend roots $name
	} else {
	    lappend leaves $name
	}
    }
    foreach name $leaves {

	emitInit $name text
    }


    foreach name $roots {



	emitInit $name text
    }

    rewriteFile [file join $outDir ${libraryName}StubInit.c] $text
}

# genStubs::init --
#
Changes to tools/genWinImage.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# genWinImage.tcl --
#
#	This script generates the Windows installer.
#
# Copyright (c) 1999 by Scriptics Corporation.
# All rights reserved.
# 
# RCS: @(#) $Id: genWinImage.tcl,v 1.2 1999/04/16 00:47:39 stanton Exp $


# This file is insensitive to the directory from which it is invoked.

namespace eval genWinImage {
    # toolsDir --
    #







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# genWinImage.tcl --
#
#	This script generates the Windows installer.
#
# Copyright (c) 1999 by Scriptics Corporation.
# All rights reserved.
# 
# RCS: @(#) $Id: genWinImage.tcl,v 1.2.4.1 1999/04/29 23:20:36 stanton Exp $


# This file is insensitive to the directory from which it is invoked.

namespace eval genWinImage {
    # toolsDir --
    #
64
65
66
67
68
69
70





















71
72
73
74
75
76
77
    set toolsDir [lindex $argv 2]

    generateInstallers
 
    puts "\n--- genWiImage.tcl finished: \
	    [clock format [clock seconds] -format "%Y%m%d-%H:%M"] --\n\n"
}






















# genWinImage::generateInstallers --
#
#	Perform substitutions on the pro.wse.in file and then
#	invoke the WSE script twice; once for CD and once for web.
#
# Arguments:







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
    set toolsDir [lindex $argv 2]

    generateInstallers
 
    puts "\n--- genWiImage.tcl finished: \
	    [clock format [clock seconds] -format "%Y%m%d-%H:%M"] --\n\n"
}

# genWinImage::makeTextFile --
#
#	Convert the input file into a CRLF terminated text file.
#
# Arguments:
#	infile		The input file to convert.
#	outfile		The location where the text file should be stored.
#
# Results:
#	None.

proc genWinImage::makeTextFile {infile outfile} {
    set f [open $infile r]
    set text [read $f]
    close $f
    set f [open $outfile w]
    fconfigure $f -translation crlf
    puts -nonewline $f $text
    close $f
}

# genWinImage::generateInstallers --
#
#	Perform substitutions on the pro.wse.in file and then
#	invoke the WSE script twice; once for CD and once for web.
#
# Arguments:
98
99
100
101
102
103
104







105
106
107
108
109
110
111
    set f [open tcl.wse.in r]
    set s [read $f]
    close $f
    set s [subst -nocommands -nobackslashes $s]
    set f [open tcl.wse w]
    puts $f $s
    close $f








    set wise32ProgFilePath [file native [file join $__WISE__ wise32.exe]]

    # Run the Wise installer to create the Windows install images.

    if {[catch {exec [file native $wise32ProgFilePath] \
	    /c tcl.wse} errMsg]} {







>
>
>
>
>
>
>







119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
    set f [open tcl.wse.in r]
    set s [read $f]
    close $f
    set s [subst -nocommands -nobackslashes $s]
    set f [open tcl.wse w]
    puts $f $s
    close $f

    # Ensure the text files are CRLF terminated

    makeTextFile [file join $tclBuildDir win/README.binary] \
	    [file join $tclBuildDir win/readme.txt]
    makeTextFile [file join $tclBuildDir license.terms] \
	    [file join $tclBuildDir license.txt]

    set wise32ProgFilePath [file native [file join $__WISE__ wise32.exe]]

    # Run the Wise installer to create the Windows install images.

    if {[catch {exec [file native $wise32ProgFilePath] \
	    /c tcl.wse} errMsg]} {
Changes to tools/tcl.wse.in.
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
end
item: Set Variable
  Variable=VER
  Value=8.1
end
item: Set Variable
  Variable=PATCHLEVEL
  Value=8.1b3
end
item: Set Variable
  Variable=APPTITLE
  Value=Tcl/Tk %PATCHLEVEL% for Windows
end
item: Set Variable
  Variable=URL







|







42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
end
item: Set Variable
  Variable=VER
  Value=8.1
end
item: Set Variable
  Variable=PATCHLEVEL
  Value=8.1
end
item: Set Variable
  Variable=APPTITLE
  Value=Tcl/Tk %PATCHLEVEL% for Windows
end
item: Set Variable
  Variable=URL
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
end
item: Open/Close INSTALL.LOG
end
item: Check Disk Space
  Component=COMPONENTS
end
item: Install File
  Source=${__TCLBASEDIR__}\license.terms
  Destination=%MAINDIR%\license.txt
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\win\Readme.binary
  Destination=%MAINDIR%\Readme.txt
  Flags=0000000000000010
end
item: If/While Statement
  Variable=COMPONENTS
  Value=D
  Flags=00001010







|




|







941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
end
item: Open/Close INSTALL.LOG
end
item: Check Disk Space
  Component=COMPONENTS
end
item: Install File
  Source=${__TCLBASEDIR__}\license.txt
  Destination=%MAINDIR%\license.txt
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\win\Readme.txt
  Destination=%MAINDIR%\Readme.txt
  Flags=0000000000000010
end
item: If/While Statement
  Variable=COMPONENTS
  Value=D
  Flags=00001010
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
  Flags=0000000010000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\msgcat1.0\msgcat.tcl
  Destination=%MAINDIR%\lib\tcl%VER%\msgcat1.0\msgcat.tcl
  Flags=0000000010000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\ksc5601.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\ksc5601.enc
  Flags=0000000010000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\euc-kr.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\euc-kr.enc
  Flags=0000000010000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\symbol.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\symbol.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\shiftjis.enc







<
<
<
<
<
<
<
<
<
<







1057
1058
1059
1060
1061
1062
1063










1064
1065
1066
1067
1068
1069
1070
  Flags=0000000010000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\msgcat1.0\msgcat.tcl
  Destination=%MAINDIR%\lib\tcl%VER%\msgcat1.0\msgcat.tcl
  Flags=0000000010000010
end










item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\symbol.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\symbol.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\shiftjis.enc
1137
1138
1139
1140
1141
1142
1143










1144
1145
1146
1147
1148
1149
1150
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\macCentEuro.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\macCentEuro.enc
  Flags=0000000000000010
end










item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\jis0212.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\jis0212.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\jis0208.enc







>
>
>
>
>
>
>
>
>
>







1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\macCentEuro.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\macCentEuro.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\ksc5601.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\ksc5601.enc
  Flags=0000000010000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\koi8-r.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\ksc5601.enc
  Flags=0000000010000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\jis0212.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\jis0212.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\jis0208.enc
1227
1228
1229
1230
1231
1232
1233





1234
1235
1236
1237
1238





1239
1240
1241
1242
1243
1244
1245
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\gb12345.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\gb12345.enc
  Flags=0000000000000010
end





item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\euc-jp.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\euc-jp.enc
  Flags=0000000000000010
end





item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\dingbats.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\dingbats.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp950.enc







>
>
>
>
>





>
>
>
>
>







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
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\gb12345.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\gb12345.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\euc-cn.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\euc-cn.enc
  Flags=0000000010000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\euc-jp.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\euc-jp.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\euc-kr.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\euc-kr.enc
  Flags=0000000010000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\dingbats.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\dingbats.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp950.enc
1382
1383
1384
1385
1386
1387
1388





1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp1250.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp1250.enc
  Flags=0000000000000010
end





item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\big5.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\big5.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\ascii.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\ascii.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\opt0.4\pkgIndex.tcl
  Destination=%MAINDIR%\lib\tcl%VER%\opt0.4\pkgIndex.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\opt0.4\optparse.tcl







>
>
>
>
>





<
<
<
<
<







1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408





1409
1410
1411
1412
1413
1414
1415
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\cp1250.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\cp1250.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\ascii.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\ascii.enc
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\encoding\big5.enc
  Destination=%MAINDIR%\lib\tcl%VER%\encoding\big5.enc
  Flags=0000000000000010
end





item: Install File
  Source=${__TCLBASEDIR__}\library\opt0.4\pkgIndex.tcl
  Destination=%MAINDIR%\lib\tcl%VER%\opt0.4\pkgIndex.tcl
  Flags=0000000000000010
end
item: Install File
  Source=${__TCLBASEDIR__}\library\opt0.4\optparse.tcl
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307






2308
2309
2310
2311
2312
2313
2314
      Text Spanish=
      Text Spanish=Presione el bot�n Terminar para salir de esta instalaci�n.
      Text Italian=L'installazione %APPTITLE% � stata portata a termine con successo.
      Text Italian=
      Text Italian=Premere il pulsante Fine per uscire dall'installazione.
    end
    item: Checkbox
      Rectangle=88 156 245 170
      Variable=TO_SCRIPTICS
      Enabled Color=00000000000000001111111111111111
      Create Flags=01010000000000010000000000000011
      Text=Take me to learn more about Tcl/Tk %VER%
      Text=
    end






  end
end
item: End Block
end
item: Check Configuration
  Flags=10111011
end







|



|


>
>
>
>
>
>







2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
      Text Spanish=
      Text Spanish=Presione el bot�n Terminar para salir de esta instalaci�n.
      Text Italian=L'installazione %APPTITLE% � stata portata a termine con successo.
      Text Italian=
      Text Italian=Premere il pulsante Fine per uscire dall'installazione.
    end
    item: Checkbox
      Rectangle=88 143 245 157
      Variable=TO_SCRIPTICS
      Enabled Color=00000000000000001111111111111111
      Create Flags=01010000000000010000000000000011
      Text=Show me important information about
      Text=
    end
    item: Static
      Rectangle=99 156 245 170
      Enabled Color=00000000000000001111111111111111
      Create Flags=01010000000000000000000000000000
      Text=Tcl/Tk %VER% and TclPro
    end
  end
end
item: End Block
end
item: Check Configuration
  Flags=10111011
end
Changes to tools/tclSplash.bmp.

cannot compute difference between binary files

Changes to unix/README.



1
2
3
4
5



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



This is the directory where you configure, compile, test, and install
UNIX versions of Tcl.  This directory also contains source files for Tcl
that are specific to UNIX.  Some of the files in this directory are
used on the PC or Mac platform too, but they all depend on UNIX
(POSIX/ANSI C) interfaces and some of them only make sense under UNIX.




The rest of this file contains instructions on how to do this.  The
release should compile and run either "out of the box" or with trivial
changes on any UNIX-like system that approximates POSIX, BSD, or System
V.  We know that it runs on workstations from Sun, H-P, DEC, IBM, and
SGI, as well as PCs running Linux, BSDI, and SCO UNIX.  To compile for
a PC running Windows, see the README file in the directory ../win.  To
compile for a Macintosh, see the README file in the directory ../mac.

RCS: @(#) $Id: README,v 1.4 1999/04/16 00:48:03 stanton Exp $

How To Compile And Install Tcl:
-------------------------------

(a) Check for patches as described in ../README.

(b) If you have already compiled Tcl once in this directory and are now
>
>
>





>
>
>









|







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
Tcl UNIX README
---------------

This is the directory where you configure, compile, test, and install
UNIX versions of Tcl.  This directory also contains source files for Tcl
that are specific to UNIX.  Some of the files in this directory are
used on the PC or Mac platform too, but they all depend on UNIX
(POSIX/ANSI C) interfaces and some of them only make sense under UNIX.

Updated forms of the information found in this file is available at:
    http://www.scriptics.com/support/howto/compile.html#unix

The rest of this file contains instructions on how to do this.  The
release should compile and run either "out of the box" or with trivial
changes on any UNIX-like system that approximates POSIX, BSD, or System
V.  We know that it runs on workstations from Sun, H-P, DEC, IBM, and
SGI, as well as PCs running Linux, BSDI, and SCO UNIX.  To compile for
a PC running Windows, see the README file in the directory ../win.  To
compile for a Macintosh, see the README file in the directory ../mac.

RCS: @(#) $Id: README,v 1.4.4.1 1999/04/22 23:04:37 welch Exp $

How To Compile And Install Tcl:
-------------------------------

(a) Check for patches as described in ../README.

(b) If you have already compiled Tcl once in this directory and are now
Changes to unix/configure.in.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
dnl	This file is an input file used by the GNU "autoconf" program to
dnl	generate the file "configure", which is run during Tcl installation
dnl	to configure the system for the local environment.
AC_INIT(../generic/tcl.h)
# RCS: @(#) $Id: configure.in,v 1.32 1999/04/21 21:50:33 rjohnson Exp $

TCL_VERSION=8.1
TCL_MAJOR_VERSION=8
TCL_MINOR_VERSION=1
TCL_PATCH_LEVEL=0
VERSION=${TCL_VERSION}

if test "${prefix}" = "NONE"; then
    prefix=/usr/local
fi
if test "${exec_prefix}" = "NONE"; then
    exec_prefix=$prefix




|




|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
dnl	This file is an input file used by the GNU "autoconf" program to
dnl	generate the file "configure", which is run during Tcl installation
dnl	to configure the system for the local environment.
AC_INIT(../generic/tcl.h)
# RCS: @(#) $Id: configure.in,v 1.32.2.2 1999/04/29 02:07:36 stanton Exp $

TCL_VERSION=8.1
TCL_MAJOR_VERSION=8
TCL_MINOR_VERSION=1
TCL_PATCH_LEVEL=
VERSION=${TCL_VERSION}

if test "${prefix}" = "NONE"; then
    prefix=/usr/local
fi
if test "${exec_prefix}" = "NONE"; then
    exec_prefix=$prefix
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
	SHLIB_LD_LIBS=""
	SHLIB_SUFFIX=".so"
	DL_OBJS="tclLoadDl.o"
	DL_LIBS="-ldl"
	LD_FLAGS="-Wl,-Bexport"
	LD_SEARCH_FLAGS=""
	;;
    NetBSD-*|FreeBSD-*|OpenBSD-*)
	# Not available on all versions:  check for include file.
	AC_CHECK_HEADER(dlfcn.h, [
	    SHLIB_CFLAGS="-fpic"
	    SHLIB_LD="ld -Bshareable -x"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"







|







903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
	SHLIB_LD_LIBS=""
	SHLIB_SUFFIX=".so"
	DL_OBJS="tclLoadDl.o"
	DL_LIBS="-ldl"
	LD_FLAGS="-Wl,-Bexport"
	LD_SEARCH_FLAGS=""
	;;
    NetBSD-*|FreeBSD-[12].*|OpenBSD-*)
	# Not available on all versions:  check for include file.
	AC_CHECK_HEADER(dlfcn.h, [
	    SHLIB_CFLAGS="-fpic"
	    SHLIB_LD="ld -Bshareable -x"
	    SHLIB_LD_LIBS=""
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
931
932
933
934
935
936
937











938
939
940
941
942
943
944
	    TCL_SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.a'
	])

	# FreeBSD doesn't handle version numbers with dots.

	TCL_UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.a'
	TCL_LIB_VERSIONS_OK=nodots











	;;
    NEXTSTEP-*)
	SHLIB_CFLAGS=""
	SHLIB_LD="cc -nostdlib -r"
	SHLIB_LD_LIBS=""
	SHLIB_SUFFIX=".so"
	DL_OBJS="tclLoadNext.o"







>
>
>
>
>
>
>
>
>
>
>







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
	    TCL_SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.a'
	])

	# FreeBSD doesn't handle version numbers with dots.

	TCL_UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}\$\{DBGX\}.a'
	TCL_LIB_VERSIONS_OK=nodots
        ;;
    FreeBSD-*)
        # FreeBSD 3.* and greater have ELF.
        SHLIB_CFLAGS="-fpic"
        SHLIB_LD="ld -Bshareable -x"
        SHLIB_LD_LIBS=""
        SHLIB_SUFFIX=".so"
        DL_OBJS="tclLoadDl.o"
        DL_LIBS=""
        LD_FLAGS=""
        LD_SEARCH_FLAGS=""
	;;
    NEXTSTEP-*)
	SHLIB_CFLAGS=""
	SHLIB_LD="cc -nostdlib -r"
	SHLIB_LD_LIBS=""
	SHLIB_SUFFIX=".so"
	DL_OBJS="tclLoadNext.o"
Changes to win/README.
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
Tcl 8.1 for Windows

by Scott Stanton
Scriptics Corporation
[email protected]

RCS: @(#) $Id: README,v 1.10 1999/04/16 00:48:06 stanton Exp $

1. Introduction
---------------

This is the directory where you configure and compile the Windows
version of Tcl.  This directory also contains source files for Tcl
that are specific to Microsoft Windows.  The rest of this file
contains information specific to the Windows version of Tcl.

2. Distribution notes
---------------------

Tcl 8.1 for Windows is distributed in binary form in addition to the
common source release.  The binary distribution is a self-extracting
archive with a built-in installation script.

Look for the binary release in the same location as the source release
(ftp.scriptics.com:/pub/tcl or any of the mirror sites).  For most users,
the binary release will be much easier to install and use.  You only
need the source release if you plan to modify the core of Tcl, or if
you need to compile with a different compiler.  With the addition of
the dynamic loading interface, it is no longer necessary to have the
source distribution in order to build and use extensions.

3. Compiling Tcl
----------------

In order to compile Tcl for Windows, you need the following items:

	Tcl 8.1 Source Distribution (plus any patches)

	Visual C++ 2.x/4.x/5.x

In practice, the 8.1.a2 release is built with Visual C++ 5.0

In the "win" subdirectory of the source release, you will find two
files called "makefile.bc" and "makefile.vc".  These are the makefiles
for the Borland and Visual C++ compilers respectively.  You should
copy the appropriate one to "makefile" and update the paths at the
top of the file to reflect your system configuration.  Now you can use
"make" (or "nmake" for VC++) to build the tcl libraries and the tclsh
executable.

In order to use the binaries generated by these makefiles, you will
need to place the Tcl script library files someplace where Tcl can
find them.  Tcl looks in one of three places for the library files:

	1) The path specified in the environment variable "TCL_LIBRARY".







|






|
<

<
<
|
<
<
<
|
<
<
<
<
<
<
<

|








|

|
<
|
<
|
|
|







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
Tcl 8.1 for Windows

by Scott Stanton
Scriptics Corporation
[email protected]

RCS: @(#) $Id: README,v 1.10.4.1 1999/04/22 23:04:38 welch Exp $

1. Introduction
---------------

This is the directory where you configure and compile the Windows
version of Tcl.  This directory also contains source files for Tcl
that are specific to Microsoft Windows.




The information in this file is maintained on the web at:



    http://www.scriptics.com/support/howto/compile.html#win








2. Compiling Tcl
----------------

In order to compile Tcl for Windows, you need the following items:

	Tcl 8.1 Source Distribution (plus any patches)

	Visual C++ 2.x/4.x/5.x

In practice, the 8.1 release is built with Visual C++ 5.0

In the "win" subdirectory of the source release, you will find

"makefile.vc".  This is the makefile Visual C++ compiler.  You should

update the paths at the top of the file to reflect your system
configuration.  Now you can use "make" (or "nmake" for VC++) to build
the tcl libraries and the tclsh executable.

In order to use the binaries generated by these makefiles, you will
need to place the Tcl script library files someplace where Tcl can
find them.  Tcl looks in one of three places for the library files:

	1) The path specified in the environment variable "TCL_LIBRARY".

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

Note that in order to run tclsh81.exe, you must ensure that tcl81.dll
and tclpip81.dll are on your path, in the system directory, or in the 
directory containing tclsh81.exe.

Note: Tcl no longer provides support for Win32s.

4. Building Extensions
----------------------

With the Windows compilers you have to worry about how you export symbols
from DLLs.  tcl.h defines a few macros to help solve this problem:
EXTERN - all Tcl_ function prototypes use this macro, which implies
	they are exported.  You'll see this used in tcl.h and tk.h.
	You should use this in your exported procedures.
	However, this is not the whole story.
TCL_STORAGE_CLASS - this is really an import/export flag, depending on if you are
	importing symbols from a DLL (i.e., a user of the DLL), or if
	you are exporting symbols from the DLL (i.e., you are building it.)
	The EXTERN macro includes TCL_STORAGE_CLASS.
	TCL_STORAGE_CLASS is defined to be either DLLIMPORT or DLLEXPORT as
	described below.
STATIC_BUILD - define this if you are *not* building a DLL
	(e.g., a main program)
DLL_BUILD - define this if you *are* building a DLL
DLLIMPORT - If STATIC_BUILD is defined, this becomes nothing.
	(On UNIX, DLLIMPORT is defined to be empty)
	Otherwise, this this expands to __declspec(dllimport)
DLLEXPORT - If STATIC_BUILD is defined, this becomes nothing.
	(On UNIX, DLLEXPORT is defined to be empty)
	Otherwise, this this expands to __declspec(dllexport)

EXPORT(type, func)
	For the Borland compiler, you need to export functions differently.
	The DLLEXPORT macro is empty, and instead you need to use
	EXPORT because they had a different order.  Your declaration will
	look like
	EXTERN EXPORT(int, Foo_Init)(Tcl_Interp *interp);
We have not defined EXPORT anywhere.  You can paste this into your C file:
#ifndef STATIC_BUILD
#if defined(_MSC_VER)
#   define EXPORT(a,b) __declspec(dllexport) a b
#   define DllEntryPoint DllMain
#else
#   if defined(__BORLANDC__)
#       define EXPORT(a,b) a _export b
#   else
#       define EXPORT(a,b) a b
#   endif
#endif
#endif


How to use these:

Assume your extension is named Foo.  In its Makefile, define
BUILD_Foo so that you know you are building Foo and not using it.
Then, in your main header file, foo.h, conditionally define
EXPORT to be either DLLIMPORT or DLLEXPORT based on the
presense of BUILD_Foo, like this:

#ifndef _FOO
#define _FOO
#include "tcl.h"
/* Additional includes go here */
/*
 * if the BUILD_foo macro is defined, the assumption is that we are
 * building the dynamic library.
 */
#ifdef BUILD_Foo
#  undef TCL_STORAGE_CLASS
#  define TCL_STORAGE_CLASS DLLEXPORT
#endif
/*
 * Function prototypes for this module.
 */
EXTERN int Foo_Init _ANSI_ARGS_((Tcl_Interp *interp));
EXTERN int Foo_SafeInit _ANSI_ARGS_((Tcl_Interp *interp));
/* Additional prototypes go here */
/*
 * end of foo.h
 * reset TCL_STORAGE_CLASS to DLLIMPORT.
 */
# undef TCL_STORAGE_CLASS
# define TCL_STORAGE_CLASS DLLIMPORT
#endif /* _FOO */

In your C file, put EXTERN before then functions you need to export.
If you use Borland, you'll need to use the old EXPORT macro, too.

5. Test suite
-------------

This distribution contains an extensive test suite for Tcl.  Some of
the tests are timing dependent and will fail from time to time.  If a
test is failing consistently, please send us a bug report with as much
detail as you can manage.


In order to run the test suite, you build the "test" target using the
appropriate makefile for your compiler.


6. Known Bugs
-------------

Here is the current list of known bugs/missing features for the
Windows version of Tcl:

- Clock command fails to handle daylight savings time boundaries for
  things like "last week".
- Background processes aren't properly detached on NT.
- File events only work on sockets and pipes.
- Files/console/serial ports don't support nonblocking I/O.
- Environment variables containing international characters aren't
  imported correctly.

If you have comments or bug reports for the Windows version of Tcl,
please use the form at:

http://www.scriptics.com/support/bugForm.html

If you have comments or bug reports for the Windows version of Tk,
please direct them to the comp.lang.tcl newsgroup or the
[email protected] mailing list.







<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|
<
|
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|





|
>




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
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
























Note that in order to run tclsh81.exe, you must ensure that tcl81.dll
and tclpip81.dll are on your path, in the system directory, or in the 
directory containing tclsh81.exe.

Note: Tcl no longer provides support for Win32s.



For more information about Compiling Tcl on Windows, please see





















    http://www.scriptics.com/support/howto/compile.html#win




















This page includes a lengthy discussion of compiler macros necessary

when compiling Tcl extensions that will be dynamically loaded.



































3. Test suite
-------------

This distribution contains an extensive test suite for Tcl.  Some of
the tests are timing dependent and will fail from time to time.  If a
test is failing consistently, please send us a bug report with as much
detail as you can manage.  Please use the form at
    http://www.scriptics.com/support/bugForm.html

In order to run the test suite, you build the "test" target using the
appropriate makefile for your compiler.
























Changes to win/README.binary.
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
Tcl/Tk 8.1 for Windows, Binary Distribution

RCS: @(#) $Id: README.binary,v 1.5 1999/04/21 21:50:33 rjohnson Exp $ 

1. Introduction
--------------- 

This directory contains the binary distribution of Tcl/Tk 8.1.0 for
Windows.  It was compiled with Microsoft Visual C++ 5.0 using Win32
API, so that it will run under Windows NT and Windows 95.  The
information here corresponds to the first release of 8.1.










2. Documentation
----------------

The best way to get started with Tcl is to read one of the introductory
books on Tcl:

    Practical Programming in Tcl and Tk, 2nd Edition, by Brent Welch,
    Prentice-Hall, 1997, ISBN 0-13-616830-2

    Tcl and the Tk Toolkit, by John Ousterhout,
    Addison-Wesley, 1994, ISBN 0-201-63337-X

    Exploring Expect, by Don Libes,

    O'Reilly and Associates, 1995, ISBN 1-56592-090-2



Other books are listed at
http://www.scriptics.com/resource/doc/books/
http://www.tclconsortium.org/resources/books.html

There is also an official home for Tcl and Tk on the Web:
	http://www.scriptics.com
These Web pages include information about the latest releases, products
related to Tcl and Tk, reports on bug fixes and porting issues, HTML
versions of the manual pages, and pointers to many other Tcl/Tk Web
pages at other sites.  Check them out!

3. Installation
---------------

The binary release is distributed as a self-extracting archive called
tcl81.exe.  The setup program which will prompt you for an
installation directory.  It will create the installation heirarchy
under the specified directory, and install a wish application icon
under the program manager group of your choice.

We are no longer supporting use of Tcl with 16-bit versions of
Windows.  Microsoft has completely dropped support of the Win32s
subsystem.

4. Summary of changes in Tcl 8.1
--------------------------------
The most important changes in Tcl 8.1 are summarized below. See
the README and changes files in the distribution
for more complete information on what has changed, including both feature
changes and bug fixes.

Internationalization.  Tcl has undergone a major
revision to support international character sets:


All strings in Tcl are now represented in UTF-8 instead of ASCII, so
that Tcl now supports the full Unicode character set.
The representation of ASCII characters is unchanged (in UTF-8 anything
that looks like an ASCII character is an ASCII character), but
characters with the high-order bit set, such as those in ISO-8859,
are represented with multi-byte sequences, as are all Unicode
characters with values greater than 127.  This change does not affect
Tcl scripts but it does affect C code that parses strings.
Tcl automatically translates between UTF-8 and the normal encoding for
the platform during interactions with the system.

In Tcl scripts the backslash sequence \u can be used to enter
16-bit Unicode characters.  \o and \x generate
only 8-bit characters as before.

The fconfigure command now supports a -encoding
option for specifying the encoding of an open file or socket.  Tcl will
automatically translate between the specified encoding and UTF-8 during
I/O.  See the directory library/encoding to find out what encodings are
supported (eventually there will be an encoding command
that makes this information more accessible).

There are several new C APIs that support UTF-8 and various encodings.
See the manual entry Utf.3 for procedures that
translate between Unicode and UTF-8 and manipulate UTF-8 strings.
See Encoding.3 for procedures that create new encodings and
translate between encodings.  See ToUpper.3 for procedures
that perform case conversions on UTF-8 strings.

Binary data.  Binary data is handled differently in Tcl 8.1 than in
Tcl 8.0.  Tcl 8.1 uses the UTF-8 facilities to represent binary data:
the character value zero is represented with a multi-byte sequence, so
that (once again) strings in Tcl 8.1 never contain null bytes.  This
means that binary data is now accepted everywhere in Tcl and Tk (in
Tcl 8.0 the support for binary data was incomplete).  If you have C
code that needs to manipulate the bytes of binary data (as opposed to
just passing the data through) you should use a new object type called
"byte array".  See the manual entry ByteArrObj.3 for information about
procedures such as Tcl_GetByteArrayFromObj.

New regular expressions.  Tcl 8.1 contains a brand new implementation
of regular expressions from Henry Spencer.  This new version supports
almost all of the Perl extensions and it also handles UTF-8 and binary
data.

Multi-Threading.  Tcl 8.1 is multi-thread safe.  Each thread can
contain several Tcl interpreters, but a given interpreter can not be
accessed from more than one thread.  Each thread runs its own event
loop, and you can post events to other threads. There is not yet
support for tcl level use of threading except for a test
command. (Compile tcltest and try testthread.)  Tk 8.1 is not yet
multi-thread safe, and may never be due to limitations of Xlib.


What's new in Tk 8.1

The most important changes in Tk 8.1 are summarized below. See the
README and changes files in the distribution for more complete
information on what has changed, including both feature changes and
bug fixes.

1. Internationalization.  Tk has undergone a major overhaul to support
the new internationalization features of Tcl.  The font package has
been rewritten to support arbitrary Unicode characters; when you
specify a particular font such as "Times 12" Tk may actually use
additional fonts to display Unicode characters that don't exist in the
font you chose.  Tk guarantees to find a way to display any Unicode
character regardless of the font you selected, as long as there is
some font in the system that contains the Unicode character.  The
input method support in Tk has also been modified to support full
Unicode characters.

2. Send/DDE support.  The send command now works on Windows platforms.
It is implemented using DDE and there is a new dde command that allows
Tk applications to use DDE to communicate with other Windows
applications.  send still doesn't work on the Macintosh.

3. Configuration options.  There is a new library of C procedures for
manipulating widget configuration options using Tcl_Objs instead of
strings.  This should eventually make Tk much more efficient.  Label,
button, checkbutton, radiobutton, and menu widgets have been modified
to use the new library.  See SetOptions.3 for information on the new C
APIs.

4. More Tcl_Obj support.  Several additional C library procedures have
been added to support Tcl_Objs.  See the manual entries 3DBorder.3,
GetAnchor.3, GetBitmap.3, GetColor.3, GetCursor.3, GetFont.3,
GetJustify.3, and GetPixels.3.

Incompatibilities

Although the 8.1 releases involve substantial changes to the
implementation of Tcl and Tk, the changes should introduce few
if any compatibility problems for Tcl scripts or extensions.  Here
are the compatibility problems that we know of:

The changes to the regular expression package required a few minor
syntax changes in order to support all the new features:

- Backslash inside brackets is an escape whereas before it was a
  literal character.  To specify a literal \ in brackets you must
  write \\.

- Some escapes, such as \d, \s, and \w, now mean special things in a
  bracket expression.  Other escapes , such as \D, \S, \W, \A and \Z,
  are illegal.
  
- A { followed by a digit will no longer match those two characters.
  Instead, it will start a bound.  Such sequences should be rare and
  will often result in an error because the following characters will
  not look like a valid bound.
  
- Backslash followed by an alphanumeric character is either an escape
  or an error.  Several of the new escapes were treated as literal
  characters in earlier versions of Tcl.
  
- The matching order has changed slightly.  Here is an explanation
  from Henry Spencer:

    Both the old package and the new package find the match that starts
    earliest in the string.  Where things get tricky is when there is more
    than one possible match starting at that point, different in either
    length or internal details (that is, which subexpressions match where).

    The old package examines possible matches in a complex but well-defined
    order, and simply reports the first one it finds.  The new package
    examines all possible matches simultaneously, and reports the longest.
    For example, (week|wee)(night|knights) matches all of "weeknights".

    When two possible matches are of the same length, priority is decided
    based on getting the longest possible matches for early subexpressions,
    with later subexpressions accepting whatever they can get.  This means
    that either (wee|week)(kly|ly) or (week*)(k?ly) matches "weekly" as
    week-ly, not wee-kly.  More subtly, when .*|a.c matches "abc", the .*
    matches the whole string and the a.c doesn't even get a chance to
    participate. 

    When non-greedy quantifiers are used, things get more complicated.  If
    all quantifiers in a regular expression are non-greedy, the exact same
    rules apply except with "longest" replaced by "shortest" everywhere.
    When greedy and non-greedy quantifiers are mixed, it's complicated and
    difficult to explain.

Known Problems With These Releases

Both the internationalization support and the new regular expression
package are large, complicated, and young, which means there are
likely to be lots of bugs.  We need your help in finding and fixing
problems.  This is particularly important for internationalization,
since we don't have the right equipment or knowledge to test
under very many conditions.  Here are some of the most glaring bugs
or missing features that we know of:

- We haven't been able to test input methods in Tk under Unix to be
  sure that the full Unicode character set is being substituted
  properly in %A substitutions.  This means that it probably doesn't
  work.  We have been able to test under Windows and the Macintosh.

- In Tk, PostScript generation does not work correctly for characters
  outside the ASCII subset.

- The threading for Tcl is brand new so there are likely to be bugs,
  although it is based on early work done by Richard Hipp.  We have
  done some testing on a multiprocessor Solaris machine, but none on
  Windows or other flavors of UNIX on a multiprocessor.

6. Known Bugs/Missing Features
------------------------------

- Clock command fails to handle daylight savings time boundaries for
  things like "last week".
- Background processes aren't properly detached on NT.
- File events only work on sockets and pipes.
- Files/console/serial ports don't support nonblocking I/O.
- There is no support for custom cursors/application icons.  The core
  set of X cursors is supported, although you cannot change their color.
- Stippling of arcs isn't implemented yet.
- Some "wm" functions don't map to Windows and aren't implemented;
  others should map, but just aren't implemented.  The worst offenders
  are the icon manipulation routines.
- Color management on some displays doesn't work properly resulting in
  Tk switching to monochrome mode.
- Tk seems to fail to draw anything on some Matrox Millenium cards.
- Printing does not work for images (e.g. GIF) on a canvas.
- Tk_dialog appears in the upper left corner.  This is a symptom of a
  larger problem with "wm geometry" when applied to unmapped or
  iconified windows.
- PPM images are using the wrong translation mode for writing to
  files, resulting in CR/LF terminated PPM files.
- Tk crashes if the display depth changes while it is running.  Tk
  also doesn't consistently track changes in the system colors.

There may be more that we don't know about, so be sure to submit bug
reports when you run into problems.  If you have comments or bug
reports for the Windows version of Tcl, please use our on-line bug
form at:

http://www.scriptics.com/support/bugForm.html

or post them to the newsgroup comp.lang.tcl.

7. Tcl newsgroup
-----------------


|






|
|
>
>
>
>
>
>
>
>
>




|
|

|
|

|
|

|
>
|
>
>

|
|
<

|
|
<
<
<
<














|
|
<
<
<
<

<
<
|
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
|
|
<

<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
|
<
<
<
|
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
|
<
<
<
<

|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|







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
Tcl/Tk 8.1 for Windows, Binary Distribution

RCS: @(#) $Id: README.binary,v 1.5.2.1 1999/04/22 23:04:38 welch Exp $ 

1. Introduction
--------------- 

This directory contains the binary distribution of Tcl/Tk 8.1.0 for
Windows.  It was compiled with Microsoft Visual C++ 5.0 using Win32
API, so that it will run under Windows NT, Windows 95, and Windows 98.

Tcl provides a powerful platform for creating integration applications
that tie together diverse applications, protocols, devices, and
frameworks.  When paired with the Tk toolkit, Tcl provides the fastest
and most powerful way to create GUI applications that run on PCs, Unix,
and the Macintosh.  Tcl can also be used for a variety of web-related
tasks and for creating powerful command languages for applications.

Tcl is maintained, enhanced, and distributed freely as a service to the
Tcl community by Scriptics Corporation.

2. Documentation
----------------

The official home for Tcl and Tk on the Web is at:
	http://www.scriptics.com

The home page for the Tcl/Tk 8.1 release is
    http://www.scriptics.com/software/8.1.html

Information about new features in Tcl/Tk 8.1 can be found at
    http://www.scriptics.com/software/whatsnew81.html

Detailed release notes can be found at
    http://www.scriptics.com/software/relnotes/tcl8.1

Information about Tcl itself can be found at
    http://www.scriptics.com/scripting/

There are many Tcl books on the market.  Most are listed at
    http://www.scriptics.com/resource/doc/books/


There are notes about compiling Tcl at
	http://www.scriptics.com/support/howto/compile.html





3. Installation
---------------

The binary release is distributed as a self-extracting archive called
tcl81.exe.  The setup program which will prompt you for an
installation directory.  It will create the installation heirarchy
under the specified directory, and install a wish application icon
under the program manager group of your choice.

We are no longer supporting use of Tcl with 16-bit versions of
Windows.  Microsoft has completely dropped support of the Win32s
subsystem.

4. Linking against the binary release
--------------------------------------







In order to link your applications against the .dll files shipped with
this release, you will need to use the appropriate .lib file for your










compiler.  In the lib directory of the installation directory, there



are library files for the Microsoft Visual C++ compiler:





































	tcl81.lib
	tk81.lib






5. Building dynamically loadable extensions










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


























Please refer to the example dynamically loadable extension provided on



our ftp site:








	ftp://ftp.scriptics.com/pub/tcl/misc/example.zip








































This archive contains a template that you can use for building




extensions that will be loadable on Unix, Windows, and Macintosh


systems.





6. Reporting Bugs
-----------------


























If you have comments or bug reports for the Windows version of Tcl,
please use our on-line bug form at:

http://www.scriptics.com/support/bugForm.html

or post them to the newsgroup comp.lang.tcl.

7. Tcl newsgroup
-----------------
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
would just like to receive more information about the list without
subscribing put the line:

	information mactcl
	
in the body instead (or wintcl).

11. Tcl version numbers
----------------------

Each Tcl release is identified by two numbers separated by a dot, e.g.
6.7 or 7.0.  If a new release contains changes that are likely to break
existing C code or Tcl scripts then the major release number increments
and the minor number resets to zero: 6.0, 7.0, etc.  If a new release
contains only bug fixes and compatible changes, then the minor number
increments without changing the major number, e.g. 7.1, 7.2, etc.  If
you have C code or Tcl scripts that work with release X.Y, then they
should also work with any release X.Z as long as Z > Y.

Alpha and beta releases have an additional suffix of the form b1 or b1.
For example, Tcl 7.0b1 is the first beta release of Tcl version 7.0,
Tcl 7.0b2 is the second beta release, and so on.  A beta release is an
initial version of a new release, used to fix bugs and bad features before
declaring the release stable.  An alpha release is like a beta release,
except it's likely to need even more work before it's "ready for prime
time".  New releases are normally preceded by one or more alpha and beta
releases.  We hope that lots of people will try out the alpha and beta
releases and report problems.  We'll make new alpha/beta releases to fix
the problems, until eventually there is a beta release that appears to
be stable.  Once this occurs we'll make the final release.

We can't promise to maintain compatibility among alpha and beta releases.
For example, release 7.1b2 may not be backward compatible with 7.1b1, even
though the final 7.1 release will be backward compatible with 7.0.  This
allows us to change new features as we find problems during beta testing.
We'll try to minimize incompatibilities between beta releases, but if
a major problem turns up then we'll fix it even if it introduces an
incompatibility.  Once the official release is made then there won't
be any more incompatibilities until the next release with a new major
version number.

Patch releases have a suffix such as p1 or p2.  These releases contain
bug fixes only.  A patch release (e.g Tcl 7.6p2) should be completely
compatible with the base release from which it is derived (e.g. Tcl
7.6), and you should normally use the highest available patch release.

As of 8.0.3, the patch releases use a second . instead of 'p'.  So, the
8.0 release went to 8.0p1, 8.0p2, and 8.0.3.  The alphas and betas will
still use the 'a' and 'b' letters in their tcl_patchLevel.

12. Linking against the binary release
--------------------------------------

In order to link your applications against the .dll files shipped with
this release, you will need to use the appropriate .lib file for your
compiler.  In the lib directory of the installation directory, there
are library files for the Microsoft Visual C++ compiler:

	tcl81.lib
	tk81.lib

13. Building dynamically loadable extensions
--------------------------------------------

Please refer to the example dynamically loadable extension provided on
our ftp site:

	ftp://ftp.scriptics.com/pub/tcl/misc/example.zip

This archive contains a template that you can use for building
extensions that will be loadable on Unix, Windows, and Macintosh
systems.







<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
143
144
145
146
147
148
149


150






























































would just like to receive more information about the list without
subscribing put the line:

	information mactcl
	
in the body instead (or wintcl).


































































Added win/pkgIndex.tcl.
























>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
# Tcl package index file, version 1.0
# This file contains package information for Windows-specific extensions.
#
# Copyright (c) 1997 by Sun Microsystems, Inc.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
# 
# RCS: @(#) $Id: pkgIndex.tcl,v 1.3 1999/04/16 00:48:07 stanton Exp $

package ifneeded registry 1.0 [list tclPkgSetup $dir registry 1.0 {{tclreg81.dll load registry}}]
package ifneeded dde 1.0 [list tclPkgSetup $dir dde 1.0 {{tcldde81.dll load dde}}]
Changes to win/tcl.rc.
1
2
3
4


5
6
7
8
9
10
11
// RCS: @(#) $Id: tcl.rc,v 1.3 1999/04/16 00:48:07 stanton Exp $
//
// Version
//



#define RESOURCE_INCLUDED
#include <tcl.h>

LANGUAGE 0x9, 0x1	/* LANG_ENGLISH, SUBLANG_DEFAULT */

VS_VERSION_INFO VERSIONINFO
|



>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
// RCS: @(#) $Id: tcl.rc,v 1.3.4.1 1999/04/27 21:37:14 stanton Exp $
//
// Version
//

#define VS_VERSION_INFO 1

#define RESOURCE_INCLUDED
#include <tcl.h>

LANGUAGE 0x9, 0x1	/* LANG_ENGLISH, SUBLANG_DEFAULT */

VS_VERSION_INFO VERSIONINFO
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0" /* LANG_ENGLISH/SUBLANG_ENGLISH_US, Unicode CP */
        BEGIN
            VALUE "FileDescription", "Tcl DLL\0"
            VALUE "OriginalFilename", "tcl" STRINGIFY(TCL_MAJOR_VERSION) STRINGIFY(TCL_MINOR_VERSION) ".dll\0"
            VALUE "CompanyName", "Sun Microsystems, Inc\0"
            VALUE "FileVersion", TCL_PATCH_LEVEL
            VALUE "LegalCopyright", "Copyright (c) 1995-1997\0"
            VALUE "ProductName", "Tcl " TCL_VERSION " for Windows\0"
            VALUE "ProductVersion", TCL_PATCH_LEVEL
        END		    
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1200







|

|







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0" /* LANG_ENGLISH/SUBLANG_ENGLISH_US, Unicode CP */
        BEGIN
            VALUE "FileDescription", "Tcl DLL\0"
            VALUE "OriginalFilename", "tcl" STRINGIFY(TCL_MAJOR_VERSION) STRINGIFY(TCL_MINOR_VERSION) ".dll\0"
            VALUE "CompanyName", "Scriptics Corporation\0"
            VALUE "FileVersion", TCL_PATCH_LEVEL
            VALUE "LegalCopyright", "Copyright (c) 1999 by Scriptics Corporation\0"
            VALUE "ProductName", "Tcl " TCL_VERSION " for Windows\0"
            VALUE "ProductVersion", TCL_PATCH_LEVEL
        END		    
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1200
Changes to win/tcl16.rc.
1
2
3
4
5
6
7
8
// RCS: @(#) $Id: tcl16.rc,v 1.2 1998/09/14 18:40:19 stanton Exp $
//
// Version
//

#define RESOURCE_INCLUDED
#include <tcl.h>

|







1
2
3
4
5
6
7
8
// RCS: @(#) $Id: tcl16.rc,v 1.2.10.1 1999/04/27 21:37:14 stanton Exp $
//
// Version
//

#define RESOURCE_INCLUDED
#include <tcl.h>

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0"
        BEGIN
            VALUE "FileDescription", "Tcl16 DLL, 16-bit thunking module\0"
            VALUE "OriginalFilename", "tcl16" STRINGIFY(TCL_MAJOR_VERSION) STRINGIFY(TCL_MINOR_VERSION) ".dll\0"
            VALUE "CompanyName", "Sun Microsystems, Inc\0"
            VALUE "FileVersion", TCL_PATCH_LEVEL
            VALUE "LegalCopyright", "Copyright \251 1995-1996\0"
            VALUE "ProductName", "Tcl " TCL_VERSION " for Windows\0"
            VALUE "ProductVersion", TCL_PATCH_LEVEL
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1200
    END
END









|

|











17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0"
        BEGIN
            VALUE "FileDescription", "Tcl16 DLL, 16-bit thunking module\0"
            VALUE "OriginalFilename", "tcl16" STRINGIFY(TCL_MAJOR_VERSION) STRINGIFY(TCL_MINOR_VERSION) ".dll\0"
            VALUE "CompanyName", "Scriptics Corporation\0"
            VALUE "FileVersion", TCL_PATCH_LEVEL
            VALUE "LegalCopyright", "Copyright \251 1999 by Scriptics Corporation\0"
            VALUE "ProductName", "Tcl " TCL_VERSION " for Windows\0"
            VALUE "ProductVersion", TCL_PATCH_LEVEL
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1200
    END
END


Changes to win/tclWinPort.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
 * tclWinPort.h --
 *
 *	This header file handles porting issues that occur because of
 *	differences between Windows and Unix. It should be the only
 *	file that contains #ifdefs to handle different flavors of OS.
 *
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: tclWinPort.h,v 1.9 1999/04/22 20:28:02 redman Exp $
 */

#ifndef _TCLWINPORT
#define _TCLWINPORT

#ifndef _TCLINT
#   include "tclInt.h"












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
 * tclWinPort.h --
 *
 *	This header file handles porting issues that occur because of
 *	differences between Windows and Unix. It should be the only
 *	file that contains #ifdefs to handle different flavors of OS.
 *
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: tclWinPort.h,v 1.8 1999/04/16 00:48:09 stanton Exp $
 */

#ifndef _TCLWINPORT
#define _TCLWINPORT

#ifndef _TCLINT
#   include "tclInt.h"
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <process.h>
#include <signal.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/timeb.h>
#include <tchar.h>
#include <time.h>
#include <winsock2.h>

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN

#ifdef BUILD_tcl
# undef TCL_STORAGE_CLASS







|







52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <process.h>
#include <signal.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/timeb.h>
#include <tchar.h>
#include <time.h>
#include <winsock.h>

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#undef WIN32_LEAN_AND_MEAN

#ifdef BUILD_tcl
# undef TCL_STORAGE_CLASS
Changes to win/tclWinSock.c.
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
/* 
 * tclWinSock.c --
 *
 *	This file contains Windows-specific socket related code.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: tclWinSock.c,v 1.9 1999/04/22 20:28:02 redman Exp $
 */

#include "tclWinInt.h"

/*
 * The following variable is used to tell whether this module has been
 * initialized.
 */

static int initialized = 0;

static int  hostnameInitialized = 0;
static char hostname[255];	/* This buffer should be big enough for
                                 * hostname plus domain name. */
static int useThreads = 0;

static HANDLE   socketThread;  /* Thread used with WSAEventSelect to check
				  sockets for fileevents on NT (not used for
				  Win95 or Win98) */
static WSAEVENT socketEvent;   /* Event triggered by WSAEventSelect, for all
				  sockets, NT only */
static WSAEVENT killEvent;     /* Event used to kill off the socketThread, NT
				  only */

static CRITICAL_SECTION socketCS; /* Critical Section used even when building
				     without threads */
TCL_DECLARE_MUTEX(socketMutex)    /* Mutex used when built with multithreading
				   */ 

    
/*
 * The following structure contains pointers to all of the WinSock API entry
 * points used by Tcl.  It is initialized by InitSockets.  Since we
 * dynamically load Winsock.dll on demand, we must use this function table
 * to refer to functions in the socket API.
 */











|














<
<
<
<
<
<
<
<
<
<
<
<
|
<

<







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
/* 
 * tclWinSock.c --
 *
 *	This file contains Windows-specific socket related code.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * RCS: @(#) $Id: tclWinSock.c,v 1.8 1999/04/16 00:48:09 stanton Exp $
 */

#include "tclWinInt.h"

/*
 * The following variable is used to tell whether this module has been
 * initialized.
 */

static int initialized = 0;

static int  hostnameInitialized = 0;
static char hostname[255];	/* This buffer should be big enough for
                                 * hostname plus domain name. */












TCL_DECLARE_MUTEX(socketMutex)



/*
 * The following structure contains pointers to all of the WinSock API entry
 * points used by Tcl.  It is initialized by InitSockets.  Since we
 * dynamically load Winsock.dll on demand, we must use this function table
 * to refer to functions in the socket API.
 */

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
    int (PASCAL FAR *getsockname)(SOCKET sock, struct sockaddr FAR *name,
            int FAR *namelen);
    int (PASCAL FAR *WSAStartup)(WORD wVersionRequired, LPWSADATA lpWSAData);
    int (PASCAL FAR *WSACleanup)(void);
    int (PASCAL FAR *WSAGetLastError)(void);
    int (PASCAL FAR *WSAAsyncSelect)(SOCKET s, HWND hWnd, u_int wMsg,
	    long lEvent);

    /*
     * The following are used for the WinSock 2.0 for NT implementation
     */

    WSAEVENT (PASCAL FAR *WSACreateEvent)(void);
    BOOL (PASCAL FAR *WSACloseEvent)(WSAEVENT event);
    int (PASCAL FAR *WSAEventSelect)(SOCKET s, WSAEVENT event, long lEvent);
    BOOL (PASCAL FAR *WSAResetEvent)(WSAEVENT event);
    BOOL (PASCAL FAR *WSASetEvent)(WSAEVENT event);
    int (PASCAL FAR *WSAEnumNetworkEvents)(SOCKET s, WSAEVENT event,
	    LPWSANETWORKEVENTS events);
    DWORD (PASCAL FAR *WSAWaitForMultipleEvents)(DWORD cEvents,
	    const WSAEVENT FAR *events, 
	    BOOL fWaitAll, DWORD dwTimeOUT, BOOL fAlertable); 
} winSock;

/*
 * The following defines declare the messages used on socket windows.
 */

#define SOCKET_MESSAGE	WM_USER+1







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







69
70
71
72
73
74
75















76
77
78
79
80
81
82
    int (PASCAL FAR *getsockname)(SOCKET sock, struct sockaddr FAR *name,
            int FAR *namelen);
    int (PASCAL FAR *WSAStartup)(WORD wVersionRequired, LPWSADATA lpWSAData);
    int (PASCAL FAR *WSACleanup)(void);
    int (PASCAL FAR *WSAGetLastError)(void);
    int (PASCAL FAR *WSAAsyncSelect)(SOCKET s, HWND hWnd, u_int wMsg,
	    long lEvent);















} winSock;

/*
 * The following defines declare the messages used on socket windows.
 */

#define SOCKET_MESSAGE	WM_USER+1
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
    int flags;			   /* Bit field comprised of the flags
				    * described below.  */
    int watchEvents;		   /* OR'ed combination of FD_READ, FD_WRITE,
                                    * FD_CLOSE, FD_ACCEPT and FD_CONNECT that
				    * indicate which events are interesting. */
    int readyEvents;		   /* OR'ed combination of FD_READ, FD_WRITE,
                                    * FD_CLOSE, FD_ACCEPT and FD_CONNECT that
				    * indicate which events have occurred. Not
				    * used for the WinSock 2.0 for NT
				    * implementation. */
    int selectEvents;		   /* OR'ed combination of FD_READ, FD_WRITE,
                                    * FD_CLOSE, FD_ACCEPT and FD_CONNECT that
				    * indicate which events are currently
				    * being selected. */
    Tcl_TcpAcceptProc *acceptProc; /* Proc to call on accept. */
    ClientData acceptProcData;	   /* The data for the accept proc. */
    int lastError;		   /* Error code from last message. */







|
<
<







92
93
94
95
96
97
98
99


100
101
102
103
104
105
106
    int flags;			   /* Bit field comprised of the flags
				    * described below.  */
    int watchEvents;		   /* OR'ed combination of FD_READ, FD_WRITE,
                                    * FD_CLOSE, FD_ACCEPT and FD_CONNECT that
				    * indicate which events are interesting. */
    int readyEvents;		   /* OR'ed combination of FD_READ, FD_WRITE,
                                    * FD_CLOSE, FD_ACCEPT and FD_CONNECT that
				    * indicate which events have occurred. */


    int selectEvents;		   /* OR'ed combination of FD_READ, FD_WRITE,
                                    * FD_CLOSE, FD_ACCEPT and FD_CONNECT that
				    * indicate which events are currently
				    * being selected. */
    Tcl_TcpAcceptProc *acceptProc; /* Proc to call on accept. */
    ClientData acceptProcData;	   /* The data for the accept proc. */
    int lastError;		   /* Error code from last message. */
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
#define SOCKET_EOF		(1<<1)	/* A zero read happened on
					 * the socket. */
#define SOCKET_ASYNC_CONNECT	(1<<2)	/* This socket uses async connect. */
#define SOCKET_PENDING		(1<<3)	/* A message has been sent
					 * for this socket */

typedef struct ThreadSpecificData {
    SocketInfo *socketList;     /* List of all sockets in the thread */

    /*
     * Data need for the Win95/Win98 implementation:

     */
    
    HWND hwnd;			/* Handle to window for socket messages. */

    /*
     * Data need for the WinNT implementation:
     */
    
    HANDLE wakeEvent;           /* Event to wake up the socket thread */
    Tcl_ThreadId threadId;     /* ID of the thread */

    struct ThreadSpecificData *next; /* Next entry in the thread list */
} ThreadSpecificData;

ThreadSpecificData *firstWaitingThread; /* List of threads */

static Tcl_ThreadDataKey dataKey;

/*
 * Static functions defined in this file.
 */

static SocketInfo *	CreateSocket _ANSI_ARGS_((Tcl_Interp *interp,







<
<

<
>



|
<
<
<
<
<
<
<
<


<
<







138
139
140
141
142
143
144


145

146
147
148
149
150








151
152


153
154
155
156
157
158
159
#define SOCKET_EOF		(1<<1)	/* A zero read happened on
					 * the socket. */
#define SOCKET_ASYNC_CONNECT	(1<<2)	/* This socket uses async connect. */
#define SOCKET_PENDING		(1<<3)	/* A message has been sent
					 * for this socket */

typedef struct ThreadSpecificData {


    /*

     * Every open socket has an entry on the following list.
     */
    
    HWND hwnd;			/* Handle to window for socket messages. */
    SocketInfo *socketList;








} ThreadSpecificData;



static Tcl_ThreadDataKey dataKey;

/*
 * Static functions defined in this file.
 */

static SocketInfo *	CreateSocket _ANSI_ARGS_((Tcl_Interp *interp,
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
static void		SocketCheckProc _ANSI_ARGS_((ClientData clientData,
			    int flags));
static int		SocketEventProc _ANSI_ARGS_((Tcl_Event *evPtr,
			    int flags));
static void		SocketExitHandler _ANSI_ARGS_((ClientData clientData));
static LRESULT CALLBACK	SocketProc _ANSI_ARGS_((HWND hwnd, UINT message,
			    WPARAM wParam, LPARAM lParam));
static DWORD WINAPI     SocketThread(LPVOID arg);
static void		SocketSetupProc _ANSI_ARGS_((ClientData clientData,
			    int flags));
static void		SocketThreadExitHandler _ANSI_ARGS_((ClientData clientData));
static int		SocketsEnabled _ANSI_ARGS_((void));
static void		TcpAccept _ANSI_ARGS_((SocketInfo *infoPtr));
static int		TcpBlockProc _ANSI_ARGS_((ClientData instanceData,
			    int mode));







<







167
168
169
170
171
172
173

174
175
176
177
178
179
180
static void		SocketCheckProc _ANSI_ARGS_((ClientData clientData,
			    int flags));
static int		SocketEventProc _ANSI_ARGS_((Tcl_Event *evPtr,
			    int flags));
static void		SocketExitHandler _ANSI_ARGS_((ClientData clientData));
static LRESULT CALLBACK	SocketProc _ANSI_ARGS_((HWND hwnd, UINT message,
			    WPARAM wParam, LPARAM lParam));

static void		SocketSetupProc _ANSI_ARGS_((ClientData clientData,
			    int flags));
static void		SocketThreadExitHandler _ANSI_ARGS_((ClientData clientData));
static int		SocketsEnabled _ANSI_ARGS_((void));
static void		TcpAccept _ANSI_ARGS_((SocketInfo *infoPtr));
static int		TcpBlockProc _ANSI_ARGS_((ClientData instanceData,
			    int mode));
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

/*
 * Define version of Winsock required by Tcl.
 */

#define WSA_VERSION_REQD MAKEWORD(1,1)


/*
 *----------------------------------------------------------------------
 *
 * GetSocketState --
 *
 *	Retrieve the state of a given socket from the winsock API
 *      using WSAEnumNetWorkEvents.  Modify the state appropriately
 *      when the winsock version is wrong.
 *
 *	Assumes Mutex is held.
 *
 * Results:
 *	State of the socket in FD_* masks.
 *
 * Side effects:
 *	Modifies the infoPtr values to reflect the current state.
 *
 *----------------------------------------------------------------------
 */

int GetSocketState(SocketInfo *infoPtr)
{
    WSANETWORKEVENTS netEvents;
    int event = 0;

    if (!useThreads) {
	return infoPtr->readyEvents;
    }
    
    EnterCriticalSection(&socketCS);
    if ((*winSock.WSAEnumNetworkEvents)(infoPtr->socket,
	    socketEvent, &netEvents) == 0) {
	
	event = netEvents.lNetworkEvents;
	
	if (event & FD_CLOSE) {
	    event &= ~(FD_WRITE|FD_ACCEPT);
	}
	if (event & FD_CONNECT) {
	    /*
	     * The socket is now connected, so clear the
	     * async connect flag.
	     */
	    
	    infoPtr->flags &= ~(SOCKET_ASYNC_CONNECT);
	    
	} 
	if(infoPtr->flags & SOCKET_ASYNC_CONNECT) {
	    infoPtr->flags &= ~(SOCKET_ASYNC_CONNECT);
	    event |= FD_WRITE;
	}
    }
    LeaveCriticalSection(&socketCS);

    return event;
}

/*
 *----------------------------------------------------------------------
 *
 * InitSockets --
 *
 *	Initialize the socket module.  Attempts to load the wsock32.dll
 *	library and set up the winSock function table.  If successful,
 *	registers the event window for the socket notifier code.


 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Dynamically loads wsock32.dll, and registers a new window
 *	class and creates a window for use in asynchronous socket
 *	notification.
 *
 *----------------------------------------------------------------------
 */

static void
InitSockets()
{
    WSADATA wsaData;
    DWORD id;
    OSVERSIONINFO info;
    static WNDCLASSA class;
    ThreadSpecificData *tsdPtr = 
	(ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);

    Tcl_MutexLock(&socketMutex);
    if (! initialized) {
	
	InitializeCriticalSection(&socketCS);
	initialized = 1;
	Tcl_CreateExitHandler(SocketExitHandler, (ClientData) NULL);
    
	/*
	 * Find out if we're running on Win32s.
	 */
    
	info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	GetVersionEx(&info);
    
	/*
	 * Check to see if Sockets are supported on this system.
	 *
	 * For WinNT, use the WinSock 2.0 API to avoid creating extra windows
	 * to handle socket events.
	 *
	 * Not all versions of Win95 have WinSock 2.0, don't count on it being
	 * there.  Also, until someone can get the code to work on Win98 or
	 * Win95 with WinSock 2.0, use the window-based version for those
	 * OS's.  Major socket users (servers) will probably be on NT anyway.
	 */
    
	if ((info.dwPlatformId == VER_PLATFORM_WIN32_NT)&&
		(SearchPathA(NULL, "ws2_32", ".dll", 0, NULL, NULL) != 0) ) {
	    useThreads = 1;
	    winSock.hInstance = LoadLibraryA("ws2_32.dll");
	} else if (SearchPathA(NULL, "wsock32", ".dll", 0, NULL, NULL) != 0) {
	    winSock.hInstance = LoadLibraryA("wsock32.dll");
	} else {
	    winSock.hInstance = NULL;
	}
    
	/*
	 * Initialize the function table.
	 */
    
	if (!SocketsEnabled()) {
	    Tcl_MutexUnlock(&socketMutex);
	    return;
	}
    
	winSock.accept = (SOCKET (PASCAL FAR *)(SOCKET s,
		struct sockaddr FAR *addr, int FAR *addrlen))
	    GetProcAddress(winSock.hInstance, "accept");
	winSock.bind = (int (PASCAL FAR *)(SOCKET s,







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








>
>
















<





<

<
<











|
|
|
|
|
<
<
<
<


|
|
<
<
<










<







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

/*
 * Define version of Winsock required by Tcl.
 */

#define WSA_VERSION_REQD MAKEWORD(1,1)



























































/*
 *----------------------------------------------------------------------
 *
 * InitSockets --
 *
 *	Initialize the socket module.  Attempts to load the wsock32.dll
 *	library and set up the winSock function table.  If successful,
 *	registers the event window for the socket notifier code.
 *
 *	Assumes Mutex is held.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Dynamically loads wsock32.dll, and registers a new window
 *	class and creates a window for use in asynchronous socket
 *	notification.
 *
 *----------------------------------------------------------------------
 */

static void
InitSockets()
{
    WSADATA wsaData;

    OSVERSIONINFO info;
    static WNDCLASSA class;
    ThreadSpecificData *tsdPtr = 
	(ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);


    if (! initialized) {


	initialized = 1;
	Tcl_CreateExitHandler(SocketExitHandler, (ClientData) NULL);
    
	/*
	 * Find out if we're running on Win32s.
	 */
    
	info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
	GetVersionEx(&info);
    
	/*
	 * Check to see if Sockets are supported on this system.  Since
	 * win32s panics if we call WSAStartup on a system that doesn't
	 * have winsock.dll, we need to look for it on the system first.
	 * If we find winsock, then load the library and initialize the
	 * stub table.




	 */
    
	if ((info.dwPlatformId != VER_PLATFORM_WIN32s)
		|| (SearchPathA(NULL, "WINSOCK", ".DLL", 0, NULL, NULL) != 0)) {



	    winSock.hInstance = LoadLibraryA("wsock32.dll");
	} else {
	    winSock.hInstance = NULL;
	}
    
	/*
	 * Initialize the function table.
	 */
    
	if (!SocketsEnabled()) {

	    return;
	}
    
	winSock.accept = (SOCKET (PASCAL FAR *)(SOCKET s,
		struct sockaddr FAR *addr, int FAR *addrlen))
	    GetProcAddress(winSock.hInstance, "accept");
	winSock.bind = (int (PASCAL FAR *)(SOCKET s,
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
	winSock.getservbyname = (struct servent FAR * (PASCAL FAR *)
		(const char FAR * name, const char FAR * proto))
	    GetProcAddress(winSock.hInstance, "getservbyname");
	winSock.getsockname = (int (PASCAL FAR *)(SOCKET sock,
		struct sockaddr FAR *name, int FAR *namelen))
	    GetProcAddress(winSock.hInstance, "getsockname");
	winSock.WSAStartup = (int (PASCAL FAR *)(WORD wVersionRequired,
		LPWSADATA lpWSAData)) GetProcAddress(winSock.hInstance,
			"WSAStartup");
	winSock.WSACleanup = (int (PASCAL FAR *)(void))
	    GetProcAddress(winSock.hInstance, "WSACleanup");
	winSock.WSAGetLastError = (int (PASCAL FAR *)(void))
	    GetProcAddress(winSock.hInstance, "WSAGetLastError");
	winSock.WSAAsyncSelect = (int (PASCAL FAR *)(SOCKET s, HWND hWnd,
		u_int wMsg, long lEvent))
	    GetProcAddress(winSock.hInstance, "WSAAsyncSelect");

	if (useThreads) {
	    winSock.WSACreateEvent = (WSAEVENT (PASCAL FAR *)(void))
		GetProcAddress(winSock.hInstance, "WSACreateEvent");
	    winSock.WSACloseEvent = (BOOL (PASCAL FAR *)(WSAEVENT event))
		GetProcAddress(winSock.hInstance, "WSACloseEvent");
	    winSock.WSAEventSelect = (int (PASCAL FAR *)(SOCKET s,
		    WSAEVENT event,
		    long lEvent))
		GetProcAddress(winSock.hInstance, "WSAEventSelect");
	    winSock.WSAResetEvent = (BOOL (PASCAL FAR *)(WSAEVENT event))
		GetProcAddress(winSock.hInstance, "WSAResetEvent");
	    winSock.WSASetEvent = (BOOL (PASCAL FAR *)(WSAEVENT event))
		GetProcAddress(winSock.hInstance, "WSASetEvent");
	    winSock.WSAEnumNetworkEvents = (int (PASCAL FAR *)(SOCKET s,
		    WSAEVENT event,
		    LPWSANETWORKEVENTS events))
		GetProcAddress(winSock.hInstance, "WSAEnumNetworkEvents");
	    winSock.WSAWaitForMultipleEvents =
		(DWORD (PASCAL FAR *)(DWORD cEvents,
			const WSAEVENT FAR *events, 
			BOOL fWaitAll, DWORD dwTimeOUT, BOOL fAlertable))
		GetProcAddress(winSock.hInstance, "WSAWaitForMultipleEvents");
	}	    
	
	/*
	 * Now check that all fields are properly initialized. If not, return
	 * zero to indicate that we failed to initialize properly.
	 */
    
	if ((winSock.hInstance == NULL) ||
		(winSock.accept == NULL) ||







|
<







|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







339
340
341
342
343
344
345
346

347
348
349
350
351
352
353
354
























355
356
357
358
359
360
361
	winSock.getservbyname = (struct servent FAR * (PASCAL FAR *)
		(const char FAR * name, const char FAR * proto))
	    GetProcAddress(winSock.hInstance, "getservbyname");
	winSock.getsockname = (int (PASCAL FAR *)(SOCKET sock,
		struct sockaddr FAR *name, int FAR *namelen))
	    GetProcAddress(winSock.hInstance, "getsockname");
	winSock.WSAStartup = (int (PASCAL FAR *)(WORD wVersionRequired,
		LPWSADATA lpWSAData)) GetProcAddress(winSock.hInstance, "WSAStartup");

	winSock.WSACleanup = (int (PASCAL FAR *)(void))
	    GetProcAddress(winSock.hInstance, "WSACleanup");
	winSock.WSAGetLastError = (int (PASCAL FAR *)(void))
	    GetProcAddress(winSock.hInstance, "WSAGetLastError");
	winSock.WSAAsyncSelect = (int (PASCAL FAR *)(SOCKET s, HWND hWnd,
		u_int wMsg, long lEvent))
	    GetProcAddress(winSock.hInstance, "WSAAsyncSelect");
    
























	/*
	 * Now check that all fields are properly initialized. If not, return
	 * zero to indicate that we failed to initialize properly.
	 */
    
	if ((winSock.hInstance == NULL) ||
		(winSock.accept == NULL) ||
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
		(winSock.getservbyname == NULL) ||
		(winSock.getsockname == NULL) ||
		(winSock.WSAStartup == NULL) ||
		(winSock.WSACleanup == NULL) ||
		(winSock.WSAGetLastError == NULL) ||
		(winSock.WSAAsyncSelect == NULL)) {
	    goto unloadLibrary;
	} else if (useThreads &&
		((winSock.WSACreateEvent == NULL) ||
			(winSock.WSACloseEvent == NULL) ||
			(winSock.WSAGetLastError == NULL) ||
			(winSock.WSAEventSelect == NULL) ||
			(winSock.WSAResetEvent == NULL) ||
			(winSock.WSASetEvent == NULL) ||
			(winSock.WSAEnumNetworkEvents == NULL) ||
			(winSock.WSAWaitForMultipleEvents == NULL))) {
	    /*
	     * WinSock 2.0 not correctly installed, use 1.x
	     */
	    
	    useThreads = 0;
	}
	
	/*
	 * Create the async notification window with a new class.  We
	 * must create a new class to avoid a Windows 95 bug that causes
	 * us to get the wrong message number for socket events if the
	 * message window is a subclass of a static control.
	 */
	if (!useThreads) {
	    class.style = 0;
	    class.cbClsExtra = 0;
	    class.cbWndExtra = 0;
	    class.hInstance = TclWinGetTclInstance();
	    class.hbrBackground = NULL;
	    class.lpszMenuName = NULL;
	    class.lpszClassName = "TclSocket";
	    class.lpfnWndProc = SocketProc;
	    class.hIcon = NULL;
	    class.hCursor = NULL;
	    
	    if (!RegisterClassA(&class)) {
		TclWinConvertError(GetLastError());
		(*winSock.WSACleanup)();
		goto unloadLibrary;
	    }
	}
	
	/*
	 * Initialize the winsock library and check the version number.
	 */
	
	if ((*winSock.WSAStartup)(WSA_VERSION_REQD, &wsaData) != 0) {
		goto unloadLibrary;
	}
	if (wsaData.wVersion != WSA_VERSION_REQD) {
	    (*winSock.WSACleanup)();
	    goto unloadLibrary;
	}

    	if (useThreads) {
	    socketEvent = (*winSock.WSACreateEvent)();
	    killEvent = (*winSock.WSACreateEvent)();
	    socketThread = CreateThread(NULL, 8000, SocketThread,
		    NULL, 0, &id);
	    SetThreadPriority(socketThread, THREAD_PRIORITY_HIGHEST);
	}	
    }
    Tcl_MutexUnlock(&socketMutex);

    /*
     * Check for per-thread initialization.
     */

    EnterCriticalSection(&socketCS);
    if (tsdPtr == NULL) {
	tsdPtr = TCL_TSD_INIT(&dataKey);
	tsdPtr->socketList = NULL;
    
	if (useThreads) {
	    tsdPtr->wakeEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

	} else {
	    tsdPtr->hwnd = CreateWindowA("TclSocket", "TclSocket", 
		    WS_TILED, 0, 0, 0, 0, NULL, NULL, class.hInstance, NULL);

	    if (tsdPtr->hwnd == NULL) {
		FreeLibrary(winSock.hInstance);
		winSock.hInstance = NULL;
		LeaveCriticalSection(&socketCS);
		return;
	    }
	}
	    
	Tcl_CreateEventSource(SocketSetupProc, SocketCheckProc, NULL);
	Tcl_CreateThreadExitHandler(SocketThreadExitHandler, NULL);

	tsdPtr->threadId = Tcl_GetCurrentThread();
	tsdPtr->next = firstWaitingThread;
	firstWaitingThread = tsdPtr;

    }
    LeaveCriticalSection(&socketCS);
    return;

unloadLibrary:
    FreeLibrary(winSock.hInstance);
    winSock.hInstance = NULL;
    Tcl_MutexUnlock(&socketMutex);
    return;
}

/*
 *----------------------------------------------------------------------
 *
 * SocketsEnabled --







<
<
<
<
<
<
<
<
<
<
<
<
<
<








|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<





|

|





|
<
<
<
<
<
<
<
<
<





<




<
<
<
<
|
|
>
|
|
<
<
<
<




|
<
<
<
<
<
<





<







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
		(winSock.getservbyname == NULL) ||
		(winSock.getsockname == NULL) ||
		(winSock.WSAStartup == NULL) ||
		(winSock.WSACleanup == NULL) ||
		(winSock.WSAGetLastError == NULL) ||
		(winSock.WSAAsyncSelect == NULL)) {
	    goto unloadLibrary;














	}
	
	/*
	 * Create the async notification window with a new class.  We
	 * must create a new class to avoid a Windows 95 bug that causes
	 * us to get the wrong message number for socket events if the
	 * message window is a subclass of a static control.
	 */
    
	class.style = 0;
	class.cbClsExtra = 0;
	class.cbWndExtra = 0;
	class.hInstance = TclWinGetTclInstance();
	class.hbrBackground = NULL;
	class.lpszMenuName = NULL;
	class.lpszClassName = "TclSocket";
	class.lpfnWndProc = SocketProc;
	class.hIcon = NULL;
	class.hCursor = NULL;

	if (!RegisterClassA(&class)) {
	    TclWinConvertError(GetLastError());
	    (*winSock.WSACleanup)();
	    goto unloadLibrary;

	}
	
	/*
	 * Initialize the winsock library and check the version number.
	 */
    
	if ((*winSock.WSAStartup)(WSA_VERSION_REQD, &wsaData) != 0) {
	    goto unloadLibrary;
	}
	if (wsaData.wVersion != WSA_VERSION_REQD) {
	    (*winSock.WSACleanup)();
	    goto unloadLibrary;
	}
    }










    /*
     * Check for per-thread initialization.
     */


    if (tsdPtr == NULL) {
	tsdPtr = TCL_TSD_INIT(&dataKey);
	tsdPtr->socketList = NULL;
    




	tsdPtr->hwnd = CreateWindowA("TclSocket", "TclSocket", 
		WS_TILED, 0, 0, 0, 0, NULL, NULL, class.hInstance, NULL);

	if (tsdPtr->hwnd == NULL) {
	    goto unloadLibrary;




	}
	    
	Tcl_CreateEventSource(SocketSetupProc, SocketCheckProc, NULL);
	Tcl_CreateThreadExitHandler(SocketThreadExitHandler, NULL);
    }






    return;

unloadLibrary:
    FreeLibrary(winSock.hInstance);
    winSock.hInstance = NULL;

    return;
}

/*
 *----------------------------------------------------------------------
 *
 * SocketsEnabled --
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
 */

    /* ARGSUSED */
static int
SocketsEnabled()
{
    int enabled;
    EnterCriticalSection(&socketCS);
    enabled = (winSock.hInstance != NULL);
    LeaveCriticalSection(&socketCS);
    return enabled;
}


/*
 *----------------------------------------------------------------------
 *







|

|







467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
 */

    /* ARGSUSED */
static int
SocketsEnabled()
{
    int enabled;
    Tcl_MutexLock(&socketMutex);
    enabled = (winSock.hInstance != NULL);
    Tcl_MutexUnlock(&socketMutex);
    return enabled;
}


/*
 *----------------------------------------------------------------------
 *
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
 */

    /* ARGSUSED */
static void
SocketExitHandler(clientData)
    ClientData clientData;              /* Not used. */
{
    EnterCriticalSection(&socketCS);
    if (useThreads && (socketThread != NULL)) {
	LeaveCriticalSection(&socketCS);
	(*winSock.WSASetEvent)(killEvent);
	WaitForSingleObject(socketThread, INFINITE);
	EnterCriticalSection(&socketCS);
	CloseHandle(socketThread);
	(*winSock.WSACloseEvent)(killEvent);
	(*winSock.WSACloseEvent)(socketEvent);
    }
    if (winSock.hInstance) {
	if (!useThreads) {
	    UnregisterClassA("TclSocket", TclWinGetTclInstance());
	}
	(*winSock.WSACleanup)();
	FreeLibrary(winSock.hInstance);
	winSock.hInstance = NULL;
    }
    initialized = 0;
    hostnameInitialized = 0;
    LeaveCriticalSection(&socketCS);
}

/*
 *----------------------------------------------------------------------
 *
 * SocketThreadExitHandler --
 *







|
<
<
<
<
<
<
<
<
<

<
|
<






|







496
497
498
499
500
501
502
503









504

505

506
507
508
509
510
511
512
513
514
515
516
517
518
519
 */

    /* ARGSUSED */
static void
SocketExitHandler(clientData)
    ClientData clientData;              /* Not used. */
{
    Tcl_MutexLock(&socketMutex);









    if (winSock.hInstance) {

	UnregisterClassA("TclSocket", TclWinGetTclInstance());

	(*winSock.WSACleanup)();
	FreeLibrary(winSock.hInstance);
	winSock.hInstance = NULL;
    }
    initialized = 0;
    hostnameInitialized = 0;
    Tcl_MutexUnlock(&socketMutex);
}

/*
 *----------------------------------------------------------------------
 *
 * SocketThreadExitHandler --
 *
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
 */

    /* ARGSUSED */
static void
SocketThreadExitHandler(clientData)
    ClientData clientData;              /* Not used. */
{
    ThreadSpecificData *tsdPtr, *nextPtr;

    tsdPtr = (ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);

    if (useThreads) {
	EnterCriticalSection(&socketCS);
	CloseHandle(tsdPtr->wakeEvent);
	
	if (firstWaitingThread == tsdPtr) {
	    firstWaitingThread = tsdPtr->next;
	} else {
	    for (nextPtr = firstWaitingThread;
		 nextPtr != NULL;
		 nextPtr = nextPtr->next) {
		
		if (nextPtr->next == tsdPtr) {
		    nextPtr->next = tsdPtr->next;
		    break;
		}
	    }
	}
	LeaveCriticalSection(&socketCS);
    } else {
	DestroyWindow(tsdPtr->hwnd);
    }

    Tcl_DeleteEventSource(SocketSetupProc, SocketCheckProc, NULL);
}

/*
 *----------------------------------------------------------------------
 *







|
<
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<







530
531
532
533
534
535
536
537

538
539



















540

541
542
543
544
545
546
547
 */

    /* ARGSUSED */
static void
SocketThreadExitHandler(clientData)
    ClientData clientData;              /* Not used. */
{
    ThreadSpecificData *tsdPtr = 

	(ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);




















    DestroyWindow(tsdPtr->hwnd);


    Tcl_DeleteEventSource(SocketSetupProc, SocketCheckProc, NULL);
}

/*
 *----------------------------------------------------------------------
 *
769
770
771
772
773
774
775

776

777
778
779
780
781
782
783
 *----------------------------------------------------------------------
 */

int
TclpHasSockets(interp)
    Tcl_Interp *interp;
{

    InitSockets();


    if (SocketsEnabled()) {
	return TCL_OK;
    }
    if (interp != NULL) {
	Tcl_AppendResult(interp, "sockets are not available on this system",
		NULL);







>

>







561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
 *----------------------------------------------------------------------
 */

int
TclpHasSockets(interp)
    Tcl_Interp *interp;
{
    Tcl_MutexLock(&socketMutex);
    InitSockets();
    Tcl_MutexUnlock(&socketMutex);

    if (SocketsEnabled()) {
	return TCL_OK;
    }
    if (interp != NULL) {
	Tcl_AppendResult(interp, "sockets are not available on this system",
		NULL);
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
SocketSetupProc(data, flags)
    ClientData data;		/* Not used. */
    int flags;			/* Event flags as passed to Tcl_DoOneEvent. */
{
    SocketInfo *infoPtr;
    Tcl_Time blockTime = { 0, 0 };
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
    int readyEvents;
    
    if (!(flags & TCL_FILE_EVENTS)) {
	return;
    }
    
    /*
     * Check to see if there is a ready socket.  If so, poll.
     */

    EnterCriticalSection(&socketCS);
    for (infoPtr = tsdPtr->socketList; infoPtr != NULL; 
	    infoPtr = infoPtr->nextPtr) {
	readyEvents = GetSocketState(infoPtr);
	if (readyEvents & infoPtr->watchEvents) {
	    Tcl_SetMaxBlockTime(&blockTime);
	    break;
	}
    }
    LeaveCriticalSection(&socketCS);
}

/*
 *----------------------------------------------------------------------
 *
 * SocketCheckProc --
 *







<
|








<


<
|




<







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
SocketSetupProc(data, flags)
    ClientData data;		/* Not used. */
    int flags;			/* Event flags as passed to Tcl_DoOneEvent. */
{
    SocketInfo *infoPtr;
    Tcl_Time blockTime = { 0, 0 };
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);


    if (!(flags & TCL_FILE_EVENTS)) {
	return;
    }
    
    /*
     * Check to see if there is a ready socket.  If so, poll.
     */


    for (infoPtr = tsdPtr->socketList; infoPtr != NULL; 
	    infoPtr = infoPtr->nextPtr) {

	if (infoPtr->readyEvents & infoPtr->watchEvents) {
	    Tcl_SetMaxBlockTime(&blockTime);
	    break;
	}
    }

}

/*
 *----------------------------------------------------------------------
 *
 * SocketCheckProc --
 *
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
 */

static void
SocketCheckProc(data, flags)
    ClientData data;		/* Not used. */
    int flags;			/* Event flags as passed to Tcl_DoOneEvent. */
{
    int readyEvents;
    SocketInfo *infoPtr;
    SocketEvent *evPtr;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
    
    if (!(flags & TCL_FILE_EVENTS)) {
	return;
    }
    
    /*
     * Queue events for any ready sockets that don't already have events
     * queued (caused by persistent states that won't generate WinSock
     * events).
     */

    EnterCriticalSection(&socketCS);
    for (infoPtr = tsdPtr->socketList; infoPtr != NULL; 
	    infoPtr = infoPtr->nextPtr) {
	readyEvents = GetSocketState(infoPtr);
	if ((readyEvents & infoPtr->watchEvents)
		&& !(infoPtr->flags & SOCKET_PENDING)) {
	    infoPtr->flags |= SOCKET_PENDING;
	    evPtr = (SocketEvent *) ckalloc(sizeof(SocketEvent));
	    evPtr->header.proc = SocketEventProc;
	    evPtr->socket = infoPtr->socket;
	    LeaveCriticalSection(&socketCS);
	    Tcl_QueueEvent((Tcl_Event *) evPtr, TCL_QUEUE_TAIL);
	    EnterCriticalSection(&socketCS);
	}
    }
    LeaveCriticalSection(&socketCS);
}

/*
 *----------------------------------------------------------------------
 *
 * SocketEventProc --
 *







<



|










<


<
|





<

<


<







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
 */

static void
SocketCheckProc(data, flags)
    ClientData data;		/* Not used. */
    int flags;			/* Event flags as passed to Tcl_DoOneEvent. */
{

    SocketInfo *infoPtr;
    SocketEvent *evPtr;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    if (!(flags & TCL_FILE_EVENTS)) {
	return;
    }
    
    /*
     * Queue events for any ready sockets that don't already have events
     * queued (caused by persistent states that won't generate WinSock
     * events).
     */


    for (infoPtr = tsdPtr->socketList; infoPtr != NULL; 
	    infoPtr = infoPtr->nextPtr) {

	if ((infoPtr->readyEvents & infoPtr->watchEvents)
		&& !(infoPtr->flags & SOCKET_PENDING)) {
	    infoPtr->flags |= SOCKET_PENDING;
	    evPtr = (SocketEvent *) ckalloc(sizeof(SocketEvent));
	    evPtr->header.proc = SocketEventProc;
	    evPtr->socket = infoPtr->socket;

	    Tcl_QueueEvent((Tcl_Event *) evPtr, TCL_QUEUE_TAIL);

	}
    }

}

/*
 *----------------------------------------------------------------------
 *
 * SocketEventProc --
 *
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
    int flags;			/* Flags that indicate what events to
				 * handle, such as TCL_FILE_EVENTS. */
{
    SocketInfo *infoPtr;
    SocketEvent *eventPtr = (SocketEvent *) evPtr;
    int mask = 0;
    int events;
    int readyEvents;
    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    if (!(flags & TCL_FILE_EVENTS)) {
	return 0;
    }

    /*
     * Find the specified socket on the socket list.
     */

    EnterCriticalSection(&socketCS);
    for (infoPtr = tsdPtr->socketList; infoPtr != NULL; 
	    infoPtr = infoPtr->nextPtr) {
	if (infoPtr->socket == eventPtr->socket) {
	    break;
	}
    }
    LeaveCriticalSection(&socketCS);

    /*
     * Discard events that have gone stale.
     */

    if (!infoPtr) {
	return 1;
    }

    infoPtr->flags &= ~SOCKET_PENDING;

    /*
     * Handle connection requests directly.
     */

    readyEvents = GetSocketState(infoPtr);
    if (readyEvents & FD_ACCEPT) {
	TcpAccept(infoPtr);
	return 1;
    }


    /*
     * Mask off unwanted events and compute the read/write mask so 
     * we can notify the channel.
     */

    events = readyEvents & infoPtr->watchEvents;

    if (events & FD_CLOSE) {
	/*
	 * If the socket was closed and the channel is still interested
	 * in read events, then we need to ensure that we keep polling
	 * for this event until someone does something with the channel.
	 * Note that we do this before calling Tcl_NotifyChannel so we don't







<










<






<















<
|










|







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
    int flags;			/* Flags that indicate what events to
				 * handle, such as TCL_FILE_EVENTS. */
{
    SocketInfo *infoPtr;
    SocketEvent *eventPtr = (SocketEvent *) evPtr;
    int mask = 0;
    int events;

    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);

    if (!(flags & TCL_FILE_EVENTS)) {
	return 0;
    }

    /*
     * Find the specified socket on the socket list.
     */


    for (infoPtr = tsdPtr->socketList; infoPtr != NULL; 
	    infoPtr = infoPtr->nextPtr) {
	if (infoPtr->socket == eventPtr->socket) {
	    break;
	}
    }


    /*
     * Discard events that have gone stale.
     */

    if (!infoPtr) {
	return 1;
    }

    infoPtr->flags &= ~SOCKET_PENDING;

    /*
     * Handle connection requests directly.
     */


    if (infoPtr->readyEvents & FD_ACCEPT) {
	TcpAccept(infoPtr);
	return 1;
    }


    /*
     * Mask off unwanted events and compute the read/write mask so 
     * we can notify the channel.
     */

    events = infoPtr->readyEvents & infoPtr->watchEvents;

    if (events & FD_CLOSE) {
	/*
	 * If the socket was closed and the channel is still interested
	 * in read events, then we need to ensure that we keep polling
	 * for this event until someone does something with the channel.
	 * Note that we do this before calling Tcl_NotifyChannel so we don't
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
	 * We must check to see if data is really available, since someone
	 * could have consumed the data in the meantime.  Turn off async
	 * notification so select will work correctly.	If the socket is
	 * still readable, notify the channel driver, otherwise reset the
	 * async select handler and keep waiting.
	 */

	if (!useThreads) {
	    (void) (*winSock.WSAAsyncSelect)(infoPtr->socket,
		    tsdPtr->hwnd, 0, 0);
	}
	
	FD_ZERO(&readFds);
	FD_SET(infoPtr->socket, &readFds);
	timeout.tv_usec = 0;
	timeout.tv_sec = 0;
 
	if ((*winSock.select)(0, &readFds, NULL, NULL, &timeout) != 0) {
	    mask |= TCL_READABLE;
	} else if (!useThreads) {
	    (void) (*winSock.WSAAsyncSelect)(infoPtr->socket, tsdPtr->hwnd,
		    SOCKET_MESSAGE, infoPtr->selectEvents);
	}
	infoPtr->readyEvents &= ~(FD_READ);

    }
    if (events & (FD_WRITE | FD_CONNECT)) {
	mask |= TCL_WRITABLE;
    }

    if (mask) {
	Tcl_NotifyChannel(infoPtr->channel, mask);







<
|
<
|
<







|


<
|
>







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
	 * We must check to see if data is really available, since someone
	 * could have consumed the data in the meantime.  Turn off async
	 * notification so select will work correctly.	If the socket is
	 * still readable, notify the channel driver, otherwise reset the
	 * async select handler and keep waiting.
	 */


	(void) (*winSock.WSAAsyncSelect)(infoPtr->socket, tsdPtr->hwnd, 0, 0);



	FD_ZERO(&readFds);
	FD_SET(infoPtr->socket, &readFds);
	timeout.tv_usec = 0;
	timeout.tv_sec = 0;
 
	if ((*winSock.select)(0, &readFds, NULL, NULL, &timeout) != 0) {
	    mask |= TCL_READABLE;
	} else {
	    (void) (*winSock.WSAAsyncSelect)(infoPtr->socket, tsdPtr->hwnd,
		    SOCKET_MESSAGE, infoPtr->selectEvents);

	    infoPtr->readyEvents &= ~(FD_READ);
	}
    }
    if (events & (FD_WRITE | FD_CONNECT)) {
	mask |= TCL_WRITABLE;
    }

    if (mask) {
	Tcl_NotifyChannel(infoPtr->channel, mask);
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
        }
    }

    /*
     * Remove the socket from socketList.
     */

    EnterCriticalSection(&socketCS);
    for (nextPtrPtr = &(tsdPtr->socketList); (*nextPtrPtr) != NULL;
	 nextPtrPtr = &((*nextPtrPtr)->nextPtr)) {
	if ((*nextPtrPtr) == infoPtr) {
	    (*nextPtrPtr) = infoPtr->nextPtr;
	    break;
	}
    }
    LeaveCriticalSection(&socketCS);

    ckfree((char *) infoPtr);
    return errorCode;
}

/*
 *----------------------------------------------------------------------







<







<







879
880
881
882
883
884
885

886
887
888
889
890
891
892

893
894
895
896
897
898
899
        }
    }

    /*
     * Remove the socket from socketList.
     */


    for (nextPtrPtr = &(tsdPtr->socketList); (*nextPtrPtr) != NULL;
	 nextPtrPtr = &((*nextPtrPtr)->nextPtr)) {
	if ((*nextPtrPtr) == infoPtr) {
	    (*nextPtrPtr) = infoPtr->nextPtr;
	    break;
	}
    }


    ckfree((char *) infoPtr);
    return errorCode;
}

/*
 *----------------------------------------------------------------------
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
    infoPtr->flags = 0;
    infoPtr->watchEvents = 0;
    infoPtr->readyEvents = 0;
    infoPtr->selectEvents = 0;
    infoPtr->acceptProc = NULL;
    infoPtr->lastError = 0;

    EnterCriticalSection(&socketCS);
    infoPtr->nextPtr = tsdPtr->socketList;
    tsdPtr->socketList = infoPtr;
    LeaveCriticalSection(&socketCS);

    return infoPtr;
}

/*
 *----------------------------------------------------------------------
 *







<


<







924
925
926
927
928
929
930

931
932

933
934
935
936
937
938
939
    infoPtr->flags = 0;
    infoPtr->watchEvents = 0;
    infoPtr->readyEvents = 0;
    infoPtr->selectEvents = 0;
    infoPtr->acceptProc = NULL;
    infoPtr->lastError = 0;


    infoPtr->nextPtr = tsdPtr->socketList;
    tsdPtr->socketList = infoPtr;


    return infoPtr;
}

/*
 *----------------------------------------------------------------------
 *
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286

	infoPtr = NewSocketInfo(sock);

	/*
	 * Set up the select mask for connection request events.
	 */

	EnterCriticalSection(&socketCS);
	infoPtr->selectEvents = FD_ACCEPT;
	infoPtr->watchEvents |= FD_ACCEPT;
	LeaveCriticalSection(&socketCS);

    } else {

        /*
         * Try to bind to a local port, if specified.
         */
        







<


<







1042
1043
1044
1045
1046
1047
1048

1049
1050

1051
1052
1053
1054
1055
1056
1057

	infoPtr = NewSocketInfo(sock);

	/*
	 * Set up the select mask for connection request events.
	 */


	infoPtr->selectEvents = FD_ACCEPT;
	infoPtr->watchEvents |= FD_ACCEPT;


    } else {

        /*
         * Try to bind to a local port, if specified.
         */
        
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
	infoPtr = NewSocketInfo(sock);

	/*
	 * Set up the select mask for read/write events.  If the connect
	 * attempt has not completed, include connect events.
	 */

	EnterCriticalSection(&socketCS);
	infoPtr->selectEvents = FD_READ | FD_WRITE | FD_CLOSE;
	if (asyncConnect) {
	    infoPtr->flags |= SOCKET_ASYNC_CONNECT;
	    infoPtr->selectEvents |= FD_CONNECT;
	}
	LeaveCriticalSection(&socketCS);
    }

    /*
     * Register for interest in events in the select mask.  Note that this
     * automatically places the socket into non-blocking mode.
     */

    if (useThreads) {
	(void) (*winSock.WSAEventSelect)(infoPtr->socket, socketEvent,
		infoPtr->selectEvents);
    } else {
	(*winSock.ioctlsocket)(sock, FIONBIO, &flag);
	(void) (*winSock.WSAAsyncSelect)(infoPtr->socket, tsdPtr->hwnd,
		SOCKET_MESSAGE, infoPtr->selectEvents);
    }
    
    return infoPtr;

error:
    TclWinConvertWSAError((*winSock.WSAGetLastError)());
    if (interp != NULL) {
	Tcl_AppendResult(interp, "couldn't open socket: ",
		Tcl_PosixError(interp), (char *) NULL);







<





<







<
<
<
<
|
|
|
|
<







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
	infoPtr = NewSocketInfo(sock);

	/*
	 * Set up the select mask for read/write events.  If the connect
	 * attempt has not completed, include connect events.
	 */


	infoPtr->selectEvents = FD_READ | FD_WRITE | FD_CLOSE;
	if (asyncConnect) {
	    infoPtr->flags |= SOCKET_ASYNC_CONNECT;
	    infoPtr->selectEvents |= FD_CONNECT;
	}

    }

    /*
     * Register for interest in events in the select mask.  Note that this
     * automatically places the socket into non-blocking mode.
     */





    (*winSock.ioctlsocket)(sock, FIONBIO, &flag);
    (void) (*winSock.WSAAsyncSelect)(infoPtr->socket, tsdPtr->hwnd,
	    SOCKET_MESSAGE, infoPtr->selectEvents);


    return infoPtr;

error:
    TclWinConvertWSAError((*winSock.WSAGetLastError)());
    if (interp != NULL) {
	Tcl_AppendResult(interp, "couldn't open socket: ",
		Tcl_PosixError(interp), (char *) NULL);
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
static int
WaitForSocketEvent(infoPtr, events, errorCodePtr)
    SocketInfo *infoPtr;	/* Information about this socket. */
    int events;			/* Events to look for. */
    int *errorCodePtr;		/* Where to store errors? */
{
    MSG msg;
    int readyEvents;
    int result = 1;
    int oldMode;
    ThreadSpecificData *tsdPtr = 
	(ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);

    /*
     * Be sure to disable event servicing so we are truly modal.
     */
    
    oldMode = Tcl_SetServiceMode(TCL_SERVICE_NONE);
	
    if (useThreads) {

	while (1) {
	    readyEvents = GetSocketState(infoPtr);
	    if (infoPtr->lastError) {
		*errorCodePtr = infoPtr->lastError;
		result = 0;
		break;
	    } else if (readyEvents & events) {
		break;
	    } else if (infoPtr->flags & SOCKET_ASYNC) {
		*errorCodePtr = EWOULDBLOCK;
		result = 0;
		break;
	    }
	    WaitForSingleObject(tsdPtr->wakeEvent, 100);
//	    Tcl_ServiceAll();
	}
    } else {
	
	/*
	 * Reset WSAAsyncSelect so we have a fresh set of events pending.
	 */

	(void) (*winSock.WSAAsyncSelect)(infoPtr->socket, tsdPtr->hwnd, 0, 0);
	(void) (*winSock.WSAAsyncSelect)(infoPtr->socket, tsdPtr->hwnd,
		SOCKET_MESSAGE, infoPtr->selectEvents);

	while (1) {
	    /*
	     * Process all outstanding messages on the socket window.
	     */
	    
	    while (PeekMessage(&msg, tsdPtr->hwnd, 0, 0, PM_REMOVE)) {
		DispatchMessage(&msg);
	    }
	    
	    if (infoPtr->lastError) {
		*errorCodePtr = infoPtr->lastError;
		result = 0;
		break;
	    } else if (infoPtr->readyEvents & events) {
		break;
	    } else if (infoPtr->flags & SOCKET_ASYNC) {
		*errorCodePtr = EWOULDBLOCK;
		result = 0;
		break;
	    }
	    
	    /*
	     * Wait until something happens.
	     */
	    
	    WaitMessage();
	}
    }
    (void) Tcl_SetServiceMode(oldMode);


    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_OpenTcpClient --







<








|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|

|
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<

>







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
static int
WaitForSocketEvent(infoPtr, events, errorCodePtr)
    SocketInfo *infoPtr;	/* Information about this socket. */
    int events;			/* Events to look for. */
    int *errorCodePtr;		/* Where to store errors? */
{
    MSG msg;

    int result = 1;
    int oldMode;
    ThreadSpecificData *tsdPtr = 
	(ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);

    /*
     * Be sure to disable event servicing so we are truly modal.
     */

    oldMode = Tcl_SetServiceMode(TCL_SERVICE_NONE);




















    
    /*
     * Reset WSAAsyncSelect so we have a fresh set of events pending.
     */

    (void) (*winSock.WSAAsyncSelect)(infoPtr->socket, tsdPtr->hwnd, 0, 0);
    (void) (*winSock.WSAAsyncSelect)(infoPtr->socket, tsdPtr->hwnd,
	    SOCKET_MESSAGE, infoPtr->selectEvents);

    while (1) {
	/*
	 * Process all outstanding messages on the socket window.
	 */

	while (PeekMessage(&msg, tsdPtr->hwnd, 0, 0, PM_REMOVE)) {
	    DispatchMessage(&msg);
	}
	
	if (infoPtr->lastError) {
	    *errorCodePtr = infoPtr->lastError;
	    result = 0;
	    break;
	} else if (infoPtr->readyEvents & events) {
	    break;
	} else if (infoPtr->flags & SOCKET_ASYNC) {
	    *errorCodePtr = EWOULDBLOCK;
	    result = 0;
	    break;
	}

	/*
	 * Wait until something happens.
	 */

	WaitMessage();
    }
    


    (void) Tcl_SetServiceMode(oldMode);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_OpenTcpClient --
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
     * Set kernel space buffering and non-blocking.
     */

    TclSockMinimumBuffers((SOCKET) sock, TCP_BUFFER_SIZE);

    infoPtr = NewSocketInfo((SOCKET) sock);

    if (infoPtr == NULL) {
	return NULL;
    }
    
    /*
     * Start watching for read/write events on the socket.
     */

    infoPtr->selectEvents = FD_READ | FD_CLOSE | FD_WRITE;

    if (useThreads) {
	(void) (*winSock.WSAEventSelect)(infoPtr->socket, socketEvent,
		infoPtr->selectEvents);
    } else {
	(void) (*winSock.WSAAsyncSelect)(infoPtr->socket, tsdPtr->hwnd,
		SOCKET_MESSAGE, infoPtr->selectEvents);
    }
    
    wsprintfA(channelName, "sock%d", infoPtr->socket);
    infoPtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName,
	    (ClientData) infoPtr, (TCL_READABLE | TCL_WRITABLE));
    Tcl_SetChannelOption(NULL, infoPtr->channel, "-translation", "auto crlf");
    return infoPtr->channel;
}








<
<
<
<





<
<
<
<
<
|
|
|
<







1378
1379
1380
1381
1382
1383
1384




1385
1386
1387
1388
1389





1390
1391
1392

1393
1394
1395
1396
1397
1398
1399
     * Set kernel space buffering and non-blocking.
     */

    TclSockMinimumBuffers((SOCKET) sock, TCP_BUFFER_SIZE);

    infoPtr = NewSocketInfo((SOCKET) sock);





    /*
     * Start watching for read/write events on the socket.
     */

    infoPtr->selectEvents = FD_READ | FD_CLOSE | FD_WRITE;





    (void) (*winSock.WSAAsyncSelect)(infoPtr->socket, tsdPtr->hwnd,
	    SOCKET_MESSAGE, infoPtr->selectEvents);


    wsprintfA(channelName, "sock%d", infoPtr->socket);
    infoPtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName,
	    (ClientData) infoPtr, (TCL_READABLE | TCL_WRITABLE));
    Tcl_SetChannelOption(NULL, infoPtr->channel, "-translation", "auto crlf");
    return infoPtr->channel;
}

1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
    /*
     * Clear the ready mask so we can detect the next connection request.
     * Note that connection requests are level triggered, so if there is
     * a request already pending, a new event will be generated.
     */

    infoPtr->readyEvents &= ~(FD_ACCEPT);
    
    if (newSocket == INVALID_SOCKET) {
        return;
    }

    /*
     * Win-NT has a misfeature that sockets are inherited in child
     * processes by default.  Turn off the inherit bit.







|







1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
    /*
     * Clear the ready mask so we can detect the next connection request.
     * Note that connection requests are level triggered, so if there is
     * a request already pending, a new event will be generated.
     */

    infoPtr->readyEvents &= ~(FD_ACCEPT);

    if (newSocket == INVALID_SOCKET) {
        return;
    }

    /*
     * Win-NT has a misfeature that sockets are inherited in child
     * processes by default.  Turn off the inherit bit.
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
    newInfoPtr = NewSocketInfo(newSocket);

    /*
     * Select on read/write events and create the channel.
     */

    newInfoPtr->selectEvents = (FD_READ | FD_WRITE | FD_CLOSE);
    if (useThreads) {
	(void) (*winSock.WSAEventSelect)(newInfoPtr->socket, socketEvent, 
		newInfoPtr->selectEvents);
    } else {
	(void) (*winSock.WSAAsyncSelect)(newInfoPtr->socket, tsdPtr->hwnd, 
		SOCKET_MESSAGE, newInfoPtr->selectEvents);
    }
    
    wsprintfA(channelName, "sock%d", newInfoPtr->socket);
    newInfoPtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName,
	    (ClientData) newInfoPtr, (TCL_READABLE | TCL_WRITABLE));
    if (Tcl_SetChannelOption(NULL, newInfoPtr->channel, "-translation",
	    "auto crlf") == TCL_ERROR) {
        Tcl_Close((Tcl_Interp *) NULL, newInfoPtr->channel);
        return;







<
<
<
<
|
|
|
<







1519
1520
1521
1522
1523
1524
1525




1526
1527
1528

1529
1530
1531
1532
1533
1534
1535
    newInfoPtr = NewSocketInfo(newSocket);

    /*
     * Select on read/write events and create the channel.
     */

    newInfoPtr->selectEvents = (FD_READ | FD_WRITE | FD_CLOSE);




    (void) (*winSock.WSAAsyncSelect)(newInfoPtr->socket, tsdPtr->hwnd, 
	    SOCKET_MESSAGE, newInfoPtr->selectEvents);


    wsprintfA(channelName, "sock%d", newInfoPtr->socket);
    newInfoPtr->channel = Tcl_CreateChannel(&tcpChannelType, channelName,
	    (ClientData) newInfoPtr, (TCL_READABLE | TCL_WRITABLE));
    if (Tcl_SetChannelOption(NULL, newInfoPtr->channel, "-translation",
	    "auto crlf") == TCL_ERROR) {
        Tcl_Close((Tcl_Interp *) NULL, newInfoPtr->channel);
        return;
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
    char *buf;				/* Where to store data. */
    int toRead;				/* Maximum number of bytes to read. */
    int *errorCodePtr;			/* Where to store error codes. */
{
    SocketInfo *infoPtr = (SocketInfo *) instanceData;
    int bytesRead;
    int error;
    int readyEvents;
    ThreadSpecificData *tsdPtr = 
	(ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
    
    *errorCodePtr = 0;

    /*
     * Check that WinSock is initialized; do not call it if not, to







<







1574
1575
1576
1577
1578
1579
1580

1581
1582
1583
1584
1585
1586
1587
    char *buf;				/* Where to store data. */
    int toRead;				/* Maximum number of bytes to read. */
    int *errorCodePtr;			/* Where to store error codes. */
{
    SocketInfo *infoPtr = (SocketInfo *) instanceData;
    int bytesRead;
    int error;

    ThreadSpecificData *tsdPtr = 
	(ThreadSpecificData *)TclThreadDataKeyGet(&dataKey);
    
    *errorCodePtr = 0;

    /*
     * Check that WinSock is initialized; do not call it if not, to
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
    if (infoPtr->flags & SOCKET_EOF) {
	return 0;
    }

    /*
     * Check to see if the socket is connected before trying to read.
     */
    infoPtr->selectEvents |= FD_READ | FD_CLOSE;

    if (useThreads) {
	(void) (*winSock.WSAEventSelect)(infoPtr->socket, socketEvent,
		infoPtr->selectEvents);
    }	
    
    if ((infoPtr->flags & SOCKET_ASYNC_CONNECT)
	    && ! WaitForSocketEvent(infoPtr,  FD_CONNECT, errorCodePtr)) {
	return -1;
    }
    
    /*
     * No EOF, and it is connected, so try to read more from the socket.
     * Note that we clear the FD_READ bit because read events are level
     * triggered so a new event will be generated if there is still data
     * available to be read.  We have to simulate blocking behavior here
     * since we are always using non-blocking sockets.
     */

    while (1) {

	if (!useThreads) {
	    (void) (*winSock.WSAAsyncSelect)(infoPtr->socket, tsdPtr->hwnd,
		    0, 0);
	}
	bytesRead = (*winSock.recv)(infoPtr->socket, buf, toRead, 0);

	infoPtr->readyEvents &= ~(FD_READ);
	
	/*
	 * Check for end-of-file condition or successful read.
	 */
  
	if (bytesRead == 0) {
	    infoPtr->flags |= SOCKET_EOF;
	}
	if (bytesRead != SOCKET_ERROR) {
	    break;
	}
  
	/*
	 * If an error occurs after the FD_CLOSE has arrived,
	 * then ignore the error and report an EOF.
	 */
	readyEvents = GetSocketState(infoPtr);
	
	if (readyEvents & FD_CLOSE) {
	    infoPtr->flags |= SOCKET_EOF;
	    bytesRead = 0;
	    break;
	}
  
	/*
	 * Check for error condition or underflow in non-blocking case.
	 */
  
	error = (*winSock.WSAGetLastError)();
	if ((error != 0) && ((infoPtr->flags & SOCKET_ASYNC)
		|| (error != WSAEWOULDBLOCK))) {
	    TclWinConvertWSAError(error);
	    *errorCodePtr = Tcl_GetErrno();
	    bytesRead = -1;
	    break;
	}

	/*
	 * In the blocking case, wait until the file becomes readable
	 * or closed and try again.
	 */

	if (!WaitForSocketEvent(infoPtr, FD_READ|FD_CLOSE, errorCodePtr)) {
	    bytesRead = -1;
	    break;
  	}
    }

    if (!useThreads) {
	(void) (*winSock.WSAAsyncSelect)(infoPtr->socket, tsdPtr->hwnd,
		SOCKET_MESSAGE, infoPtr->selectEvents);
    }
    return bytesRead;
}

/*
 *----------------------------------------------------------------------
 *
 * TcpOutputProc --







<

<
<
<
<
<














<
<
|
|
<

<

|















<
|
|










<
|
















|
<
|
|
<







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
    if (infoPtr->flags & SOCKET_EOF) {
	return 0;
    }

    /*
     * Check to see if the socket is connected before trying to read.
     */







    if ((infoPtr->flags & SOCKET_ASYNC_CONNECT)
	    && ! WaitForSocketEvent(infoPtr,  FD_CONNECT, errorCodePtr)) {
	return -1;
    }
    
    /*
     * No EOF, and it is connected, so try to read more from the socket.
     * Note that we clear the FD_READ bit because read events are level
     * triggered so a new event will be generated if there is still data
     * available to be read.  We have to simulate blocking behavior here
     * since we are always using non-blocking sockets.
     */

    while (1) {


	(void) (*winSock.WSAAsyncSelect)(infoPtr->socket, tsdPtr->hwnd,
		0, 0);

	bytesRead = (*winSock.recv)(infoPtr->socket, buf, toRead, 0);

	infoPtr->readyEvents &= ~(FD_READ);
  
	/*
	 * Check for end-of-file condition or successful read.
	 */
  
	if (bytesRead == 0) {
	    infoPtr->flags |= SOCKET_EOF;
	}
	if (bytesRead != SOCKET_ERROR) {
	    break;
	}
  
	/*
	 * If an error occurs after the FD_CLOSE has arrived,
	 * then ignore the error and report an EOF.
	 */

  
	if (infoPtr->readyEvents & FD_CLOSE) {
	    infoPtr->flags |= SOCKET_EOF;
	    bytesRead = 0;
	    break;
	}
  
	/*
	 * Check for error condition or underflow in non-blocking case.
	 */
  
	error = (*winSock.WSAGetLastError)();

	if ((infoPtr->flags & SOCKET_ASYNC) || (error != WSAEWOULDBLOCK)) {
	    TclWinConvertWSAError(error);
	    *errorCodePtr = Tcl_GetErrno();
	    bytesRead = -1;
	    break;
	}

	/*
	 * In the blocking case, wait until the file becomes readable
	 * or closed and try again.
	 */

	if (!WaitForSocketEvent(infoPtr, FD_READ|FD_CLOSE, errorCodePtr)) {
	    bytesRead = -1;
	    break;
  	}
    }
    

    (void) (*winSock.WSAAsyncSelect)(infoPtr->socket, tsdPtr->hwnd,
 	    SOCKET_MESSAGE, infoPtr->selectEvents);

    return bytesRead;
}

/*
 *----------------------------------------------------------------------
 *
 * TcpOutputProc --
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034

2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
    
    if ((infoPtr->flags & SOCKET_ASYNC_CONNECT)
	    && ! WaitForSocketEvent(infoPtr,  FD_CONNECT, errorCodePtr)) {
	return -1;
    }

    while (1) {
	if (!useThreads) {
	    (void) (*winSock.WSAAsyncSelect)(infoPtr->socket, tsdPtr->hwnd,
		    0, 0);
	}
	
	bytesWritten = (*winSock.send)(infoPtr->socket, buf, toWrite, 0);
	if (bytesWritten != SOCKET_ERROR) {
	    if (!useThreads && (infoPtr->watchEvents & FD_WRITE)) {
		/*
		 * Since Windows won't generate a new write event until we hit
		 * an overflow condition, we need to force the event loop to
		 * poll until the condition changes.
		 */


		Tcl_Time blockTime = { 0, 0 };
		Tcl_SetMaxBlockTime(&blockTime);
	    }
	    break;
	}
	
	/*
	 * Check for error condition or overflow.  In the event of overflow, we
	 * need to clear the FD_WRITE flag so we can detect the next writable
	 * event.  Note that Windows only sends a new writable event after a
	 * send fails with WSAEWOULDBLOCK.
	 */

	error = (*winSock.WSAGetLastError)();

	if (error == WSAEWOULDBLOCK) {
	    infoPtr->readyEvents &= ~(FD_WRITE);
	    if (infoPtr->flags & SOCKET_ASYNC) {
		*errorCodePtr = EWOULDBLOCK;
		bytesWritten = -1;
		break;
	    } 







<
|
|
<
<


<
|
|
|
|
|

>


|











<







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
1762
1763
1764
1765
    
    if ((infoPtr->flags & SOCKET_ASYNC_CONNECT)
	    && ! WaitForSocketEvent(infoPtr,  FD_CONNECT, errorCodePtr)) {
	return -1;
    }

    while (1) {

	(void) (*winSock.WSAAsyncSelect)(infoPtr->socket, tsdPtr->hwnd,
		0, 0);


	bytesWritten = (*winSock.send)(infoPtr->socket, buf, toWrite, 0);
	if (bytesWritten != SOCKET_ERROR) {

	    /*
	     * Since Windows won't generate a new write event until we hit
	     * an overflow condition, we need to force the event loop to
	     * poll until the condition changes.
	     */

	    if (infoPtr->watchEvents & FD_WRITE) {
		Tcl_Time blockTime = { 0, 0 };
		Tcl_SetMaxBlockTime(&blockTime);
	    }		
	    break;
	}
	
	/*
	 * Check for error condition or overflow.  In the event of overflow, we
	 * need to clear the FD_WRITE flag so we can detect the next writable
	 * event.  Note that Windows only sends a new writable event after a
	 * send fails with WSAEWOULDBLOCK.
	 */

	error = (*winSock.WSAGetLastError)();

	if (error == WSAEWOULDBLOCK) {
	    infoPtr->readyEvents &= ~(FD_WRITE);
	    if (infoPtr->flags & SOCKET_ASYNC) {
		*errorCodePtr = EWOULDBLOCK;
		bytesWritten = -1;
		break;
	    } 
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085

	if (!WaitForSocketEvent(infoPtr, FD_WRITE|FD_CLOSE, errorCodePtr)) {
	    bytesWritten = -1;
	    break;
	}
    }

    if (!useThreads) {
	(void) (*winSock.WSAAsyncSelect)(infoPtr->socket, tsdPtr->hwnd,
		SOCKET_MESSAGE, infoPtr->selectEvents);
    }
    return bytesWritten;
}

/*
 *----------------------------------------------------------------------
 *
 * TcpGetOptionProc --







<
|
|
<







1777
1778
1779
1780
1781
1782
1783

1784
1785

1786
1787
1788
1789
1790
1791
1792

	if (!WaitForSocketEvent(infoPtr, FD_WRITE|FD_CLOSE, errorCodePtr)) {
	    bytesWritten = -1;
	    break;
	}
    }


    (void) (*winSock.WSAAsyncSelect)(infoPtr->socket, tsdPtr->hwnd,
	    SOCKET_MESSAGE, infoPtr->selectEvents);

    return bytesWritten;
}

/*
 *----------------------------------------------------------------------
 *
 * TcpGetOptionProc --
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
static void
TcpWatchProc(instanceData, mask)
    ClientData instanceData;		/* The socket state. */
    int mask;				/* Events of interest; an OR-ed
                                         * combination of TCL_READABLE,
                                         * TCL_WRITABLE and TCL_EXCEPTION. */
{
    int readyEvents;
    SocketInfo *infoPtr = (SocketInfo *) instanceData;
    
    /*
     * Update the watch events mask.
     */

    EnterCriticalSection(&socketCS);
    infoPtr->watchEvents = 0;
    if (mask & TCL_READABLE) {
	infoPtr->watchEvents |= (FD_READ|FD_CLOSE|FD_ACCEPT);
    }
    if (mask & TCL_WRITABLE) {
	infoPtr->watchEvents |= (FD_WRITE|FD_CONNECT);
    }
    LeaveCriticalSection(&socketCS);

    /*
     * If there are any conditions already set, then tell the notifier to poll
     * rather than block.
     */

    readyEvents = GetSocketState(infoPtr);
    if (readyEvents & infoPtr->watchEvents) {
	Tcl_Time blockTime = { 0, 0 };
	Tcl_SetMaxBlockTime(&blockTime);
    }		
}

/*
 *----------------------------------------------------------------------







<





|
<







<






<
|







1977
1978
1979
1980
1981
1982
1983

1984
1985
1986
1987
1988
1989

1990
1991
1992
1993
1994
1995
1996

1997
1998
1999
2000
2001
2002

2003
2004
2005
2006
2007
2008
2009
2010
static void
TcpWatchProc(instanceData, mask)
    ClientData instanceData;		/* The socket state. */
    int mask;				/* Events of interest; an OR-ed
                                         * combination of TCL_READABLE,
                                         * TCL_WRITABLE and TCL_EXCEPTION. */
{

    SocketInfo *infoPtr = (SocketInfo *) instanceData;
    
    /*
     * Update the watch events mask.
     */
    

    infoPtr->watchEvents = 0;
    if (mask & TCL_READABLE) {
	infoPtr->watchEvents |= (FD_READ|FD_CLOSE|FD_ACCEPT);
    }
    if (mask & TCL_WRITABLE) {
	infoPtr->watchEvents |= (FD_WRITE|FD_CONNECT);
    }


    /*
     * If there are any conditions already set, then tell the notifier to poll
     * rather than block.
     */


    if (infoPtr->readyEvents & infoPtr->watchEvents) {
	Tcl_Time blockTime = { 0, 0 };
	Tcl_SetMaxBlockTime(&blockTime);
    }		
}

/*
 *----------------------------------------------------------------------
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
    ClientData *handlePtr;	/* Where to store the handle.  */
{
    SocketInfo *statePtr = (SocketInfo *) instanceData;

    *handlePtr = (ClientData) statePtr->socket;
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * SocketThread --
 *
 *
 * Results:
 *	0 on success.
 *
 * Side effects:
 *
 *----------------------------------------------------------------------
 */

static DWORD WINAPI
SocketThread(LPVOID arg)
{
    SocketInfo *infoPtr;
    WSAEVENT events[2];
    ThreadSpecificData *tsdPtr;
    DWORD result;
    
    /*
     * Find the specified socket on the socket list and update its
     * eventState flag.
     */

    events[0] = killEvent;
    events[1] = socketEvent;
    
    while (1) {

	result = (*winSock.WSAWaitForMultipleEvents)(2, events, FALSE,
		WSA_INFINITE, FALSE);

	switch (result) {
	    case (WSA_WAIT_EVENT_0 +1):
		/*
		 * A socket event has fired, determine which socket(s) it was
		 * and which thread(s) it came from.
		 */

		EnterCriticalSection(&socketCS);
		for (tsdPtr = firstWaitingThread; tsdPtr != NULL;
		     tsdPtr = tsdPtr->next) {
		    
		    for (infoPtr = tsdPtr->socketList; infoPtr != NULL; 
			 infoPtr = infoPtr->nextPtr) {
			
			if (GetSocketState(infoPtr) & infoPtr->watchEvents) {
			    Tcl_ThreadAlert(tsdPtr->threadId);
			    SetEvent(tsdPtr->wakeEvent);

			    /*
			     * Only process one at a time for a given thread,
			     * so break here.
			     */
			    
			    break;
			}
		    }
		}
		LeaveCriticalSection(&socketCS);
		(*winSock.WSAResetEvent)(socketEvent);
		break;

	    case WSA_WAIT_EVENT_0:
		/*
		 * This thread is supposed to kill itself off
		 */

		return 0;
		break;
		
	    default:
		/*
		 * The thread has detected a fatal error
		 */
		
		return 1;
		break;
	}
    }

    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * SocketProc --
 *
 *	This function is called when WSAAsyncSelect has been used







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







2030
2031
2032
2033
2034
2035
2036























































































2037
2038
2039
2040
2041
2042
2043
    ClientData *handlePtr;	/* Where to store the handle.  */
{
    SocketInfo *statePtr = (SocketInfo *) instanceData;

    *handlePtr = (ClientData) statePtr->socket;
    return TCL_OK;
}
























































































/*
 *----------------------------------------------------------------------
 *
 * SocketProc --
 *
 *	This function is called when WSAAsyncSelect has been used
Changes to win/tclsh.rc.
1
2
3
4


5
6
7
8
9
10
11
// RCS: @(#) $Id: tclsh.rc,v 1.3 1999/04/16 00:48:10 stanton Exp $
//
// Version
//



#define RESOURCE_INCLUDED
#include <tcl.h>

LANGUAGE 0x9, 0x1	/* LANG_ENGLISH, SUBLANG_DEFAULT */

VS_VERSION_INFO VERSIONINFO
|



>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
// RCS: @(#) $Id: tclsh.rc,v 1.3.4.1 1999/04/27 21:37:14 stanton Exp $
//
// Version
//

#define VS_VERSION_INFO 1

#define RESOURCE_INCLUDED
#include <tcl.h>

LANGUAGE 0x9, 0x1	/* LANG_ENGLISH, SUBLANG_DEFAULT */

VS_VERSION_INFO VERSIONINFO
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0"
        BEGIN
            VALUE "FileDescription", "Tclsh Application\0"
            VALUE "OriginalFilename", "tclsh" STRINGIFY(TCL_MAJOR_VERSION) STRINGIFY(TCL_MINOR_VERSION) ".exe\0"
            VALUE "CompanyName", "Sun Microsystems, Inc\0"
            VALUE "FileVersion", TCL_PATCH_LEVEL
            VALUE "LegalCopyright", "Copyright (c) 1995-1996\0"
            VALUE "ProductName", "Tcl " TCL_VERSION " for Windows\0"
            VALUE "ProductVersion", TCL_PATCH_LEVEL
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1200
    END
END








|

|










21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0"
        BEGIN
            VALUE "FileDescription", "Tclsh Application\0"
            VALUE "OriginalFilename", "tclsh" STRINGIFY(TCL_MAJOR_VERSION) STRINGIFY(TCL_MINOR_VERSION) ".exe\0"
            VALUE "CompanyName", "Scriptics Corporation\0"
            VALUE "FileVersion", TCL_PATCH_LEVEL
            VALUE "LegalCopyright", "Copyright (c) 1999 by Scriptics Corporation\0"
            VALUE "ProductName", "Tcl " TCL_VERSION " for Windows\0"
            VALUE "ProductVersion", TCL_PATCH_LEVEL
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1200
    END
END